/* ========================================================================
 * ZUI: jquery.core.js
 * ======================================================================== */
(function ($, window) {
    'use strict';

    /* Check jquery */
    if(typeof($) === 'undefined') throw new Error('ZUI requires jQuery');

    // ZUI shared object
    if(!$.zui) $.zui = function(obj) {
            if ($.isPlainObject(obj)) {
                $.extend($.zui, obj);
            }
        };

    var lastUuidAmend = 0;
    $.zui({
        IS_DEBUG: false,
        KeyPressed: {//key press state
            ctrl: false,
            shift: false
        },
        keyCode: {
            ENTER: 13, ESC: 27, END: 35, HOME: 36,
            SHIFT: 16, CTRL: 17, TAB: 9,
            LEFT: 37, RIGHT: 39, UP: 38, DOWN: 40,
            DELETE: 46, BACKSPACE: 8
        },
        eventType: {
            initUI: 'zui.initUI', // When document load completed or ajax load completed, ZUI && Plugins init
            beforeInitUI: 'zui.beforeInitUI', // If your DOM do not init [add to DOM attribute 'data-noinit="true"']
            afterInitUI: 'zui.afterInitUI', //
            ajaxStatus: 'zui.ajaxStatus', // When performing ajax request, display or hidden progress bar
            resizeGrid: 'zui.resizeGrid', // When the window or dialog resize completed
            beforeAjaxLoad: 'zui.beforeAjaxLoad', // When perform '$.fn.ajaxUrl', to do something...

            beforeLoadNavtab: 'zui.beforeLoadNavtab',
            beforeLoadDialog: 'zui.beforeLoadDialog',
            afterLoadNavtab: 'zui.afterLoadNavtab',
            afterLoadDialog: 'zui.afterLoadDialog',
            beforeCloseNavtab: 'zui.beforeCloseNavtab',
            beforeCloseDialog: 'zui.beforeCloseDialog',
            afterCloseNavtab: 'zui.afterCloseNavtab',
            afterCloseDialog: 'zui.afterCloseDialog'
        },
        //pageVar:
        pageInfo: {pageVar: 'p', pageSize: 'pageSize', orderField: 'orderField', orderDirection: 'orderDirection', total: 'total'},
        alertMsg: {displayPosition: 'topcenter', alertTimeout: 6000}, //alertmsg display position && close timeout
        ajaxReturn: {root: 'Rows',total: 'total'},
        ajaxTimeout: 30000,
        statusCode: {ok: 200, error: 300},
        keys: {status: 'status', message: 'message'},
        ui: {
            windowWidth: 0,
            showSlidebar: true, // After the ZUI initialization, display slidebar
            clientPaging: true, // Response paging and sorting information on the client
            overwriteHomeTab: false      // When open an undefined id of navtab, whether overwrite the home navtab
        },
        debug: function (msg) {
            var obj = this.IS_DEBUG;
            if (typeof(obj)=='string') {
                if(obj.substr(0, 1)=='#' || obj.substr(0, 1)=='.'){
                    obj = $(obj);
                } else {
                    obj = obj.toFunc();
                }
            }
            if(typeof(obj)=='object'){
                    if(obj.length){
                        if(obj.isTag('textarea')){
                            obj.val(msg+'\n'+obj.val());
                        } else if(obj.isTag('input')){
                            obj.val(msg);
                        } else {
                            obj.html(msg+'<br />'+obj.html());
                        }
                    }
            } else if (typeof(obj)=='function') {
                obj.call(event, msg);
            } else if (typeof(obj)=='boolean' && obj) {
                if (typeof (console) != 'undefined')
                    console.log(msg)
                else
                    alert(msg)
            }
        },
        init: function (options) {
            var op = $.extend({}, options)

            $.extend($.zui.statusCode, op.statusCode)
            $.extend($.zui.keys, op.keys)
            $.extend($.zui.pageInfo, op.pageInfo)
            $.extend($.zui.alertMsg, op.alertMsg)
            $.extend($.zui.ui, op.ui)
            if (op.PLUGINPATH)
                this.PLUGINPATH = op.PLUGINPATH
            if (op.ajaxTimeout)
                this.ajaxTimeout = op.ajaxTimeout

            this.IS_DEBUG = op.debug || false
            this.initEnv()
            if ((!$.cookie || !$.cookie('zui_theme')) && op.theme)
                $(document).theme('setTheme', op.theme, true)
        },
        initEnv: function () {
            $(window).resize(function () {
                var ww = $(this).width()

                if ($.zui.ui.windowWidth) {
                    if ($.zui.ui.windowWidth > 600 && $.zui.ui.windowWidth < ww)
                        ww = $.zui.ui.windowWidth
                }

                $.zui.initLayout(ww)
                setTimeout(function () {
                    $(this).trigger($.zui.eventType.resizeGrid)
                }, 30);
            })

            setTimeout(function () {
                var ww = $(window).width()

                if ($.zui.ui.windowWidth) {
                    if ($.zui.ui.windowWidth > 600 && $.zui.ui.windowWidth < ww)
                        ww = $.zui.ui.windowWidth
                }

                $.zui.initLayout(ww);
                $('body').initui();
            }, 10)
        },
        initLayout: function (ww) {
            var iContentW = ww - ($.zui.ui.showSlidebar ? $('#zui-sidebar').width() + 7 : 7),
                    iContentH = $(window).height() - $('#zui-header').outerHeight() - $('#zui-footer').outerHeight() - 4, //整体显示区域的高度
                    navtabH = $('#zui-navtab').find('.tabsPageHeader').height() + 1
            var $o = $('.tabsMoreList');
            if ($o) {
                $o.css('max-height', iContentH - navtabH + 1);
            }

            if ($.zui.ui.windowWidth)
                $('#zui-window').width(ww)
            $.zui.windowWidth = ww

            $('#zui-container').height(iContentH)
            $('#zui-navtab').width(iContentW)
            $('#zui-leftside, #zui-sidebar, #zui-sidebar-s, #zui-splitBar, #zui-splitBarProxy').css({height: '100%'})
            $('#zui-navtab .tabsPageContent').height(iContentH - navtabH)

            /* fixed pageFooter */
            setTimeout(function () {
                $('#zui-navtab > .tabsPageContent > .navtabPage').resizePageH()
                $('#zui-navtab > .tabsPageContent > .navtabPage').find('.zui-layout').resizePageH()
                $('#zui-navtab > .tabsPageContent > .navtabPage').find('iframe').resizePageH()
            }, 10)

            /* header navbar */
            var navbarWidth = $('body').data('zui.navbar.width'),
                    $header = $('#zui-header'), $toggle = $header.find('.zui-navbar-toggle'), $logo = $header.find('.zui-navbar-logo'), $navbar = $('#zui-navbar-collapse'), $nav = $navbar.find('.zui-navbar-right')

            if (!navbarWidth) {
                navbarWidth = {logoW: $logo.outerWidth(), navW: $nav.outerWidth()}
                $('body').data('zui.navbar.width', navbarWidth)
            }
            if (navbarWidth) {
                if (ww - navbarWidth.logoW < navbarWidth.navW) {
                    $toggle.show()
                    $navbar.addClass('collapse menu')
                } else {
                    $toggle.hide()
                    $navbar.removeClass('collapse menu in')
                }
            }
            /* horizontal navbar */
            var $hnavbox = $('#zui-hnav-navbar-box'),
                    $hnavbar = $hnavbox.find('> #zui-hnav-navbar'),
                    $hmoreL = $hnavbox.prev(),
                    $hmoreR = $hnavbox.next(),
                    hboxWidth = $hnavbox.width(),
                    liW = 0;

            $hnavbar.find('> li').each(function (i) {
                var $li = $(this)

                liW += $li.outerWidth()

                if (liW > hboxWidth) {
                    $hmoreR.show()
                    $hnavbox.data('hnav.move', true).data('hnav.liw', liW)
                } else {
                    $hmoreL.hide()
                    $hmoreR.hide()
                    $hnavbox.removeData('hnav.move')
                }
            })
        },
        regional: {},
        setRegional: function (key, value) {
            $.zui.regional[key] = value
        },
        getRegional: function (key) {
            if (String(key).indexOf('.') >= 0) {
                var msg, arr = String(key).split('.')

                for (var i = 0; i < arr.length; i++) {
                    if (!msg)
                        msg = $.zui.regional[arr[i]]
                    else
                        msg = msg[arr[i]]
                }

                return msg
            } else {
                return $.zui.regional[key]
            }
        },
        doRegional: function (frag, regional) {
            $.each(regional, function (k, v) {
                frag = frag.replaceAll('#' + k + '#', v)
            })

            return frag
        },
        // is ie browser
        isIE: function (ver) {
            var b = document.createElement('b')

            b.innerHTML = '<!--[if IE ' + ver + ']><i></i><![endif]-->'

            return b.getElementsByTagName('i').length === 1
        },
        StrBuilder: function () {
            return new StrBuilder()
        },
        uuid: function () {
            return(new Date()).getTime() * 1000 + (lastUuidAmend++) % 1000;
        },
        callEvent: function (func, event, proxy) {
            if ($.isFunction(func)) {
                if (proxy !== undefined) {
                    func = $.proxy(func, proxy);
                }
                var result = func(event);
                if(event) event.result = result;
                return !(result !== undefined && (!result));
            }
            return 1;
        },
        clientLang: function () {
            var lang = zhpConfig.lang;
            if (!lang) {
                var config = window.config;
            }
            if (typeof (config) !== 'undefined' && config.clientLang) {
                lang = config.clientLang;
            } else {
                var hl = $('html').attr('lang');
                lang = hl ? hl : (navigator.userLanguage || navigator.userLanguage || 'zh_cn');
            }
            return lang.replace('-', '_').toLowerCase();
        }
    });

    $.fn.callEvent = function (name, event, model) {
        var $this = $(this);
        var dotIndex = name.indexOf('.zui.');
        var shortName = name;
        if (dotIndex < 0 && model && model.name) {
            name += '.' + model.name;
        } else {
            shortName = name.substring(0, dotIndex);
        }
        var e = $.Event(name, event);

        if ((model === undefined) && dotIndex > 0) {
            model = $this.data(name.substring(dotIndex + 1));
        }

        if (model && model.options) {
            var func = model.options[shortName];
            if ($.isFunction(func)) {
                $.zui.callEvent(model.options[shortName], e, model);
            }
        }
        return e;
    };


    function StrBuilder() {
        this.datas = new Array();
    }

    StrBuilder.prototype.add = function (str) {
        if (typeof str !== 'undefined')
            this.datas.push(str);
        return this;
    };

    StrBuilder.prototype.toString = function (str) {
        var string = this.datas.join(str || '');
        this.clear();
        return string;
    };

    StrBuilder.prototype.isEmpty = function () {
        return this.datas.length === 0;
    };

    StrBuilder.prototype.clear = function () {
        this.datas = [];
        this.datas.length = 0;
    };
}(jQuery, window));

/* ========================================================================
 * ZUI: device.js
 * ======================================================================== */
(function (window, $) {
    'use strict';
    var desktopLg = 1200,
            desktop = 992,
            tablet = 768,
            cssNames = {
                desktop: 'screen-desktop',
                desktopLg: 'screen-desktop-wide',
                tablet: 'screen-tablet',
                phone: 'screen-phone',
                isMobile: 'device-mobile',
                isDesktop: 'device-desktop'
            };

    var $window = $(window);

    var resetCssClass = function () {
        var width = $window.width();
        $('html').toggleClass(cssNames.desktop, width >= desktop && width < desktopLg)
                .toggleClass(cssNames.desktopLg, width >= desktopLg)
                .toggleClass(cssNames.tablet, width >= tablet && width < desktop)
                .toggleClass(cssNames.phone, width < tablet)
                .toggleClass(cssNames.isMobile, width < desktop)
                .toggleClass(cssNames.isDesktop, width >= desktop);

    };

    $window.resize(resetCssClass);
    resetCssClass();
}(window, jQuery));

/* ========================================================================
 * ZUI: browser.js
 * ======================================================================== */
(function ($) {
    'use strict';

    var browseHappyTip = {
        'zh_cn': '您的浏览器版本过低，无法体验所有功能，建议升级或者更换浏览器。 <a href="http://browsehappy.com/" target="_blank" class="alert-link">了解更多...</a>',
        'zh_tw': '您的瀏覽器版本過低，無法體驗所有功能，建議升級或者更换瀏覽器。<a href="http://browsehappy.com/" target="_blank" class="alert-link">了解更多...</a>',
        'en': 'Your browser is too old, it has been unable to experience the colorful internet. We strongly recommend that you upgrade a better one. <a href="http://browsehappy.com/" target="_blank" class="alert-link">Learn more...</a>'
    };

    // The browser modal class
    var Browser = function () {
        var ie = this.isIE() || this.isIE10() || false;
        if (ie) {
            for (var i = 10; i > 5; i--) {
                if (this.isIE(i)) {
                    ie = i;
                    break;
                }
            }
        }

        this.ie = ie;

        this.cssHelper();
    };

    // Append CSS class to html tag
    Browser.prototype.cssHelper = function () {
        var ie = this.ie,
                $html = $('html');
        $html.toggleClass('ie', ie)
                .removeClass('ie-6 ie-7 ie-8 ie-9 ie-10');
        if (ie) {
            $html.addClass('ie-' + ie)
                    .toggleClass('gt-ie-7 gte-ie-8 support-ie', ie >= 8)
                    .toggleClass('lte-ie-7 lt-ie-8 outdated-ie', ie < 8)
                    .toggleClass('gt-ie-8 gte-ie-9', ie >= 9)
                    .toggleClass('lte-ie-8 lt-ie-9', ie < 9)
                    .toggleClass('gt-ie-9 gte-ie-10', ie >= 10)
                    .toggleClass('lte-ie-9 lt-ie-10', ie < 10);
        }
    };

    // Show browse happy tip
    Browser.prototype.tip = function (showCoontent) {
        var $browseHappy = $('#browseHappyTip');
        if (!$browseHappy.length) {
            $browseHappy = $('<div id="browseHappyTip" class="alert alert-dismissable alert-danger-inverse alert-block" style="position: relative; z-index: 99999"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><div class="container"><div class="content text-center"></div></div></div>');
            $browseHappy.prependTo('body');
        }

        $browseHappy.find('.content').html(showCoontent || this.browseHappyTip || browseHappyTip[$.zui.clientLang() || 'zh_cn']);
    };

    // Detect it is IE, can given a version
    Browser.prototype.isIE = function (version) {
        if(version === 10) return this.isIE10();
        var b = document.createElement('b');
        b.innerHTML = '<!--[if IE ' + (version || '') + ']><i></i><![endif]-->';
        return b.getElementsByTagName('i').length === 1;
    };

    // Detect ie 10 with hack
    Browser.prototype.isIE10 = function () {
        return (/*@cc_on!@*/false);
    };

    $.zui({
        browser: new Browser()
    });

    $(function () {
        if (!$('body').hasClass('disabled-browser-tip')) {
            if ($.zui.browser.ie && $.zui.browser.ie < 8) {
                $.zui.browser.tip();
            }
        }
    });
}(jQuery));

/* ========================================================================
 * ZUI: date.js
 * ======================================================================== */
(function () {
    'use strict';

    /**
     * Ticks of a whole day
     * @type {number}
     */
    Date.ONEDAY_TICKS = 24 * 3600 * 1000;

    if (!Date.prototype.formatDateTm) {

        /**
         * dateFmt:%y-%M-%d
         * %y-%M-{%d+1}
         * ex: new Date().formatDateTm('%y-%M-{%d-1}')
         *     new Date().formatDateTm('2012-1')
         */
        Date.prototype.formatDateTm = function (dateFmt) {
            var y = this.getFullYear();
            var m = this.getMonth() + 1;
            var d = this.getDate();
            var sDate = dateFmt.replaceAll('%y', y).replaceAll('%M', m).replaceAll('%d', d);

            sDate = replaceTmEval(sDate);

            var _y = 1900, _m = 0, _d = 1;
            var aDate = sDate.split('-');

            if (aDate.length > 0)
                _y = aDate[0];
            if (aDate.length > 1)
                _m = aDate[1] - 1;
            if (aDate.length > 2)
                _d = aDate[2];

            return new Date(_y, _m, _d).format('yyyy-MM-dd');
        };
    }

    function _isInteger(val) {
        return new RegExp(/^\d+$/).test(val);
    }

    function _getInt(str, i, minlength, maxlength) {
        for (var x = maxlength; x >= minlength; x--) {
            var token = str.substring(i, i + x);

            if (token.length < minlength) {
                return null;
            }
            if (_isInteger(token)) {
                return token;
            }
        }
        return null;
    }

    /**
     * parseDate( date_string , format_string )
     *
     * This function takes a date string and a format string. It matches
     * If the date string matches the format string, it returns the date.
     * If it does not match, it returns 0.
     * @param {Object} val
     * @param {Object} format
     */
    function parseDate(val, format) {
        val = val + '';
        format = format + '';

        var i_val = 0, i_format = 0, c = '', token = '', token2 = '', x, y, now = new Date(1900, 0, 1), year = now.getYear(), month = now.getMonth() + 1, date = 1, hh = now.getHours(), mm = now.getMinutes(), ss = now.getSeconds(), ampm = '';

        while (i_format < format.length) {
            // Get next token from format string
            c = format.charAt(i_format);
            token = '';
            while (format.charAt(i_format) === c && i_format < format.length) {
                token += format.charAt(i_format++);
            }
            // Extract contents of value based on format token
            if (token === 'yyyy' || token === 'yy' || token === 'y') {
                if (token === 'yyyy') {
                    x = 4;
                    y = 4;
                }
                if (token === 'yy') {
                    x = 2;
                    y = 2;
                }
                if (token === 'y') {
                    x = 2;
                    y = 4;
                }
                year = _getInt(val, i_val, x, y);
                if (year === null) {
                    return 0;
                }
                i_val += year.length;
                if (year.length === 2) {
                    if (year > 70) {
                        year = 1900 + (year - 0);
                    } else {
                        year = 2e3 + (year - 0);
                    }
                }
            } else if (token === 'MMM' || token === 'NNN') {
                month = 0;
                for (var i = 0; i < MONTH_NAMES.length; i++) {
                    var month_name = MONTH_NAMES[i];

                    if (val.substring(i_val, i_val + month_name.length).toLowerCase() === month_name.toLowerCase()) {
                        if (token === 'MMM' || token === 'NNN' && i > 11) {
                            month = i + 1;
                            if (month > 12) {
                                month -= 12;
                            }
                            i_val += month_name.length;
                            break;
                        }
                    }
                }
                if (month < 1 || month > 12) {
                    return 0;
                }
            } else if (token === 'EE' || token === 'E') {
                for (var i = 0; i < DAY_NAMES.length; i++) {
                    var day_name = DAY_NAMES[i];
                    if (val.substring(i_val, i_val + day_name.length).toLowerCase() === day_name.toLowerCase()) {
                        i_val += day_name.length;
                        break
                    }
                }
            } else if (token === 'MM' || token === 'M') {
                month = _getInt(val, i_val, token.length, 2);
                if (month === null || month < 1 || month > 12) {
                    return 0;
                }
                i_val += month.length;
            } else if (token === 'dd' || token === 'd') {
                date = _getInt(val, i_val, token.length, 2);
                if (date === null || date < 1 || date > 31) {
                    return 0;
                }
                i_val += date.length;
            } else if (token === 'hh' || token === 'h') {
                hh = _getInt(val, i_val, token.length, 2);
                if (hh === null || hh < 1 || hh > 12) {
                    return 0;
                }
                i_val += hh.length;
            } else if (token == 'HH' || token == 'H') {
                hh = _getInt(val, i_val, token.length, 2)
                if (hh == null || hh < 0 || hh > 23) {
                    return 0
                }
                i_val += hh.length
            } else if (token == 'KK' || token == 'K') {
                hh = _getInt(val, i_val, token.length, 2)
                if (hh == null || hh < 0 || hh > 11) {
                    return 0
                }
                i_val += hh.length
            } else if (token == 'kk' || token == 'k') {
                hh = _getInt(val, i_val, token.length, 2)
                if (hh == null || hh < 1 || hh > 24) {
                    return 0
                }
                i_val += hh.length
                hh--
            } else if (token == 'mm' || token == 'm') {
                mm = _getInt(val, i_val, token.length, 2)
                if (mm == null || mm < 0 || mm > 59) {
                    return 0
                }
                i_val += mm.length
            } else if (token == 'ss' || token == 's') {
                ss = _getInt(val, i_val, token.length, 2)
                if (ss == null || ss < 0 || ss > 59) {
                    return 0
                }
                i_val += ss.length
            } else if (token == 'a') {
                if (val.substring(i_val, i_val + 2).toLowerCase() == 'am') {
                    ampm = 'AM'
                } else if (val.substring(i_val, i_val + 2).toLowerCase() == 'pm') {
                    ampm = 'PM'
                } else {
                    return 0
                }
                i_val += 2
            } else {
                if (val.substring(i_val, i_val + token.length) != token) {
                    return 0
                } else {
                    i_val += token.length
                }
            }
        }
        // If there are any trailing characters left in the value, it doesn't match
        if (i_val != val.length) {
            return 0
        }
        // Is date valid for month?
        if (month == 2) {
            // Check for leap year
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                // leap year
                if (date > 29) {
                    return 0
                }
            } else {
                if (date > 28) {
                    return 0
                }
            }
        }
        if (month == 4 || month == 6 || month == 9 || month == 11) {
            if (date > 30) {
                return 0
            }
        }
        // Correct hours value
        if (hh < 12 && ampm == 'PM') {
            hh = hh - 0 + 12
        } else if (hh > 11 && ampm == 'AM') {
            hh -= 12
        }

        return new Date(year, month - 1, date, hh, mm, ss)
    }

    String.prototype.parseDate = function (dateFmt) {
        if (this.length < dateFmt.length) {
            dateFmt = dateFmt.slice(0, this.length)
        }
        return parseDate(this, dateFmt)
    }

    /**
     * replaceTmEval('{1+2}-{2-1}')
     */
    function replaceTmEval(data) {
        return data.replace(RegExp('({[A-Za-z0-9_+-]*})', 'g'), function ($1) {
            return eval('(' + $1.replace(/[{}]+/g, '') + ')')
        })
    }
    /**
     * 对Date的扩展，将 Date 转化为指定格式的String
     * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
     * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
     * 例子：
     * (new Date()).format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
     * (new Date()).format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18       *
     * @param  string   format
     * @return string
     */
    if (!Date.prototype.format) {
        Date.prototype.format = function (format) {
            var date = {
                'M+': this.getMonth() + 1,
                'd+': this.getDate(),
                'h+': this.getHours(),
                'm+': this.getMinutes(),
                's+': this.getSeconds(),
                'q+': Math.floor((this.getMonth() + 3) / 3),
                'S+': this.getMilliseconds()
            };
            if (/(y+)/i.test(format)) {
                format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
            }
            for (var k in date) {
                if (new RegExp('(' + k + ')').test(format)) {
                    format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? date[k] : ('00' + date[k]).substr(('' + date[k]).length));
                }
            }
            return format;
        };
    }

    /**
     * Add milliseconds to the date
     * @param {number} value
     */
    if (!Date.prototype.addMilliseconds) {
        Date.prototype.addMilliseconds = function (value) {
            this.setTime(this.getTime() + value);
            return this;
        };
    }


    /**
     * Add days to the date
     * @param {number} days
     */
    if (!Date.prototype.addDays) {
        Date.prototype.addDays = function (days) {
            this.addMilliseconds(days * Date.ONEDAY_TICKS);
            return this;
        };
    }


    /**
     * Clone a new date instane from the date
     * @return {Date}
     */
    if (!Date.prototype.clone) {
        Date.prototype.clone = function () {
            var date = new Date();
            date.setTime(this.getTime());
            return date;
        };
    }


    /**
     * Judge the year is in a leap year
     * @param  {integer}  year
     * @return {Boolean}
     */
    if (!Date.isLeapYear) {
        Date.isLeapYear = function (year) {
            return(((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
        };
    }

    if (!Date.getDaysInMonth) {
        /**
         * Get days number of the date
         * @param  {integer} year
         * @param  {integer} month
         * @return {integer}
         */
        Date.getDaysInMonth = function (year, month) {
            return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
        };
    }


    /**
     * Judge the date is in a leap year
     * @return {Boolean}
     */
    if (!Date.prototype.isLeapYear) {
        Date.prototype.isLeapYear = function () {
            return Date.isLeapYear(this.getFullYear());
        };
    }


    /**
     * Clear time part of the date
     * @return {date}
     */
    if (!Date.prototype.clearTime) {
        Date.prototype.clearTime = function () {
            this.setHours(0);
            this.setMinutes(0);
            this.setSeconds(0);
            this.setMilliseconds(0);
            return this;
        };
    }


    /**
     * Get days of this month of the date
     * @return {integer}
     */
    if (!Date.prototype.getDaysInMonth) {
        Date.prototype.getDaysInMonth = function () {
            return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
        };
    }


    /**
     * Add months to the date
     * @param {date} value
     */
    if (!Date.prototype.addMonths) {
        Date.prototype.addMonths = function (value) {
            var n = this.getDate();
            this.setDate(1);
            this.setMonth(this.getMonth() + value);
            this.setDate(Math.min(n, this.getDaysInMonth()));
            return this;
        };
    }


    /**
     * Get last week day of the date
     * @param  {integer} day
     * @return {date}
     */
    if (!Date.prototype.getLastWeekday) {
        Date.prototype.getLastWeekday = function (day) {
            day = day || 1;

            var d = this.clone();
            while (d.getDay() != day) {
                d.addDays(-1);
            }
            d.clearTime();
            return d;
        };
    }


    /**
     * Judge the date is same day as another date
     * @param  {date}  date
     * @return {Boolean}
     */
    if (!Date.prototype.isSameDay) {
        Date.prototype.isSameDay = function (date) {
            return date.toDateString() === this.toDateString();
        };
    }


    /**
     * Judge the date is in same week as another date
     * @param  {date}  date
     * @return {Boolean}
     */
    if (!Date.prototype.isSameWeek) {
        Date.prototype.isSameWeek = function (date) {
            var weekStart = this.getLastWeekday();
            var weekEnd = weekStart.clone().addDays(7);
            return date >= weekStart && date < weekEnd;
        };
    }


    /**
     * Judge the date is in same year as another date
     * @param  {date}  date
     * @return {Boolean}
     */
    if (!Date.prototype.isSameYear) {
        Date.prototype.isSameYear = function (date) {
            return this.getFullYear() === date.getFullYear();
        };
    }
}());

/* ========================================================================
 * ZUI: string.js
 * ======================================================================== */
(function () {
    'use strict';

    if (!String.prototype.format) {
        String.prototype.format = function (args) {
            var result = this;
            if (arguments.length > 0) {
                var reg;
                if (arguments.length == 1 && typeof (args) == "object") {
                    for (var key in args) {
                        if (args[key] !== undefined) {
                            reg = new RegExp("({" + key + "})", "g");
                            result = result.replace(reg, args[key]);
                        }
                    }
                } else {
                    for (var i = 0; i < arguments.length; i++) {
                        if (arguments[i] !== undefined) {
                            reg = new RegExp("({[" + i + "]})", "g");
                            result = result.replace(reg, arguments[i]);
                        }
                    }
                }
            }
            return result;
        };
    }

    /**
     * Judge the string is a integer number
     *
     * @access public
     * @return bool
     */
    if (!String.prototype.isNum) {
        String.prototype.isNum = function (s) {
            if (s !== null) {
                var r, re;
                re = /\d*/i;
                r = s.match(re);
                return(r == s) ? true : false;
            }
            return false;
        };
    }

    /**
     * JS判断一个值是否存在数组中
     */
    // 定义一个判断函数
    var in_array = function (arr) {
        // 判断参数是不是数组
        var isArr = arr && console.log(
                typeof arr === 'object' ? arr.constructor === Array ? arr.length ? arr.length === 1 ? arr[0] : arr.join(',') : 'an empty array' : arr.constructor : typeof arr
                );
        // 不是数组则抛出异常
        if (!isArr) {
            throw "arguments is not Array";
        }
        // 遍历是否在数组中
        for (var i = 0, k = arr.length; i < k; i++) {
            if (this == arr[i]) {
                return true;
            }
        }
        // 如果不在数组中就会返回false
        return false;
    }
    // 给字符串添加原型
    String.prototype.in_array = in_array;
    // 给数字类型添加原型
    Number.prototype.in_array = in_array;

    /**
     比较完整的模拟sprintf函数功能。可用的格式化通配符：
     1.%% - 返回百分号本身
     2.%b - 二进制数字
     3.%c - ASCII对应的字符
     4.%d - 整数
     5.%f - 浮点数
     6.%o - 八进制数字
     7.%s - 字符串
     8.%x - 16进制数字 (小写字母形式)
     9.%X - 16进制数字 (大写字母形式)

     在 % 号和通配字符之间可用的选项包括 (比如 %.2f)：

     1.+      (强制在数字前面显示 + 和 - 符号作为正负数标记。缺省情况下只有负数才显示 - 符号)
     2.-      (变量左对齐)
     3.0      (使用0作为右对齐的填充字符)
     4.[0-9]  (设置变量的最小宽度)
     5..[0-9] (设置浮点数精度或字符串的长度)
     */
    if (!String.prototype.sprintf)
    {
        String.prototype.sprintf = function (args) {
            function convert(match, nosign) {
                if (nosign) {
                    match.sign = '';
                } else {
                    match.sign = match.negative ? '-' : match.sign;
                }
                var l = match.min - match.argument.length + 1 - match.sign.length;
                var pad = new Array(l < 0 ? 0 : l).join(match.pad);
                if (!match.left) {
                    if (match.pad == "0" || nosign) {
                        return match.sign + pad + match.argument;
                    } else {
                        return pad + match.sign + match.argument;
                    }
                } else {
                    if (match.pad == "0" || nosign) {
                        return match.sign + match.argument + pad.replace(/0/g, ' ');
                    } else {
                        return match.sign + match.argument + pad;
                    }
                }
            }
            if (typeof arguments == "undefined") {
                return this;
            }
            if (!arguments.length) {
                return this;
            }
            if (typeof RegExp == "undefined") {
                return this;
            }
            var string = this;
            var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
            var matches = new Array();
            var strings = new Array();
            var convCount = 0;
            var stringPosStart = 0;
            var stringPosEnd = 0;
            var matchPosEnd = 0;
            var newString = '';
            var match = null;
            while (match = exp.exec(string)) {
                if (match[9]) {
                    convCount += 1;
                }
                stringPosStart = matchPosEnd;
                stringPosEnd = exp.lastIndex - match[0].length;
                strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
                matchPosEnd = exp.lastIndex;
                matches[matches.length] = {
                    match: match[0],
                    left: match[3] ? true : false,
                    sign: match[4] || '',
                    pad: match[5] || ' ',
                    min: match[6] || 0,
                    precision: match[8],
                    code: match[9] || '%',
                    negative: parseInt(arguments[convCount]) < 0 ? true : false,
                    argument: String(arguments[convCount - 1])
                };
            }
            strings[strings.length] = string.substring(matchPosEnd);

            if (matches.length == 0) {
                return string;
            }
            //if ((arguments.length) < convCount) {
            //    return null;
            //}
            var code = null;
            var match = null;
            var i = null;
            var substitution = '';
            for (i = 0; i < matches.length; i++) {
                if (matches[i].code == '%') {
                    substitution = '%'
                }
                else if (matches[i].code == 'b') {
                    matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
                    substitution = convert(matches[i], true);
                }
                else if (matches[i].code == 'c') {
                    matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
                    substitution = convert(matches[i], true);
                }
                else if (matches[i].code == 'd') {
                    matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
                    substitution = convert(matches[i]);
                }
                else if (matches[i].code == 'f') {
                    matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
                    substitution = convert(matches[i]);
                }
                else if (matches[i].code == 'o') {
                    matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
                    substitution = convert(matches[i]);
                }
                else if (matches[i].code == 's') {
                    matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
                    substitution = convert(matches[i], true);
                }
                else if (matches[i].code == 'x') {
                    matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                    substitution = convert(matches[i]);
                }
                else if (matches[i].code == 'X') {
                    matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                    substitution = convert(matches[i]).toUpperCase();
                }
                else {
                    substitution = matches[i].match;
                }
                newString += strings[i];
                newString += substitution;
            }
            newString += strings[i];
            return newString;
        }
    }
})();

/* ========================================================================
 * ZUI: jQuery resize event - v1.1 - 3/14/2010
 * ------------------------------------------------------------------------
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Project Home - http://benalman.com/projects/jquery-resize-plugin/
 * GitHub       - http://github.com/cowboy/jquery-resize/
 * Source       - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.js
 * (Minified)   - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.min.js (1.0kb)
 * ======================================================================== */
(function ($, window, undefined) {
    '$:nomunge'; // Used by YUI compressor.

    // A jQuery object containing all non-window elements to which the resize
    // event is bound.
    var elems = $([]),
            // Extend $.resize if it already exists, otherwise create it.
            jq_resize = $.resize = $.extend($.resize, {}),
            timeout_id,
            // Reused strings.
            str_setTimeout = 'setTimeout',
            str_resize = 'resize',
            str_data = str_resize + '-special-event',
            str_delay = 'delay',
            str_throttle = 'throttleWindow';

    // Property: jQuery.resize.delay
    //
    // The numeric interval (in milliseconds) at which the resize event polling
    // loop executes. Defaults to 250.

    jq_resize[str_delay] = 250;

    // Property: jQuery.resize.throttleWindow
    //
    // Throttle the native window object resize event to fire no more than once
    // every <jQuery.resize.delay> milliseconds. Defaults to true.
    //
    // Because the window object has its own resize event, it doesn't need to be
    // provided by this plugin, and its execution can be left entirely up to the
    // browser. However, since certain browsers fire the resize event continuously
    // while others do not, enabling this will throttle the window resize event,
    // making event behavior consistent across all elements in all browsers.
    //
    // While setting this property to false will disable window object resize
    // event throttling, please note that this property must be changed before any
    // window object resize event callbacks are bound.
    jq_resize[str_throttle] = true;
    // Event: resize event
    //
    // Fired when an element's width or height changes. Because browsers only
    // provide this event for the window element, for other elements a polling
    // loop is initialized, running every <jQuery.resize.delay> milliseconds
    // to see if elements' dimensions have changed. You may bind with either
    // .resize( fn ) or .bind( "resize", fn ), and unbind with .unbind( "resize" ).
    //
    // Usage:
    //
    // > jQuery('selector').bind( 'resize', function(e) {
    // >   // element's width or height has changed!
    // >   ...
    // > });
    //
    // Additional Notes:
    //
    // * The polling loop is not created until at least one callback is actually
    //   bound to the 'resize' event, and this single polling loop is shared
    //   across all elements.
    //
    // Double firing issue in jQuery 1.3.2:
    //
    // While this plugin works in jQuery 1.3.2, if an element's event callbacks
    // are manually triggered via .trigger( 'resize' ) or .resize() those
    // callbacks may double-fire, due to limitations in the jQuery 1.3.2 special
    // events system. This is not an issue when using jQuery 1.4+.
    //
    // > // While this works in jQuery 1.4+
    // > $(elem).css({ width: new_w, height: new_h }).resize();
    // >
    // > // In jQuery 1.3.2, you need to do this:
    // > var elem = $(elem);
    // > elem.css({ width: new_w, height: new_h });
    // > elem.data( 'resize-special-event', { width: elem.width(), height: elem.height() } );
    // > elem.resize();

    $.event.special[str_resize] = {
        // Called only when the first 'resize' event callback is bound per element.
        setup: function () {
            // Since window has its own native 'resize' event, return false so that
            // jQuery will bind the event using DOM methods. Since only 'window'
            // objects have a .setTimeout method, this should be a sufficient test.
            // Unless, of course, we're throttling the 'resize' event for window.
            if (!jq_resize[str_throttle] && this[str_setTimeout]) {
                return false;
            }

            var elem = $(this);

            // Add this element to the list of internal elements to monitor.
            elems = elems.add(elem);

            // Initialize data store on the element.
            $.data(this, str_data, {
                w: elem.width(),
                h: elem.height()
            });

            // If this is the first element added, start the polling loop.
            if (elems.length === 1) {
                loopy();
            }
        },
        // Called only when the last 'resize' event callback is unbound per element.
        teardown: function () {
            // Since window has its own native 'resize' event, return false so that
            // jQuery will unbind the event using DOM methods. Since only 'window'
            // objects have a .setTimeout method, this should be a sufficient test.
            // Unless, of course, we're throttling the 'resize' event for window.
            if (!jq_resize[str_throttle] && this[str_setTimeout]) {
                return false;
            }

            var elem = $(this);

            // Remove this element from the list of internal elements to monitor.
            elems = elems.not(elem);

            // Remove any data stored on the element.
            elem.removeData(str_data);

            // If this is the last element removed, stop the polling loop.
            if (!elems.length) {
                clearTimeout(timeout_id);
            }
        },
        // Called every time a 'resize' event callback is bound per element (new in
        // jQuery 1.4).
        add: function (handleObj) {
            // Since window has its own native 'resize' event, return false so that
            // jQuery doesn't modify the event object. Unless, of course, we're
            // throttling the 'resize' event for window.
            if (!jq_resize[str_throttle] && this[str_setTimeout]) {
                return false;
            }

            var old_handler;

            // The new_handler function is executed every time the event is triggered.
            // This is used to update the internal element data store with the width
            // and height when the event is triggered manually, to avoid double-firing
            // of the event callback. See the "Double firing issue in jQuery 1.3.2"
            // comments above for more information.

            function new_handler(e, w, h) {
                var elem = $(this),
                        data = $.data(this, str_data) || {};

                // If called from the polling loop, w and h will be passed in as
                // arguments. If called manually, via .trigger( 'resize' ) or .resize(),
                // those values will need to be computed.
                data.w = w !== undefined ? w : elem.width();
                data.h = h !== undefined ? h : elem.height();

                old_handler.apply(this, arguments);
            };

            // This may seem a little complicated, but it normalizes the special event
            // .add method between jQuery 1.4/1.4.1 and 1.4.2+
            if ($.isFunction(handleObj)) {
                // 1.4, 1.4.1
                old_handler = handleObj;
                return new_handler;
            } else {
                // 1.4.2+
                old_handler = handleObj.handler;
                handleObj.handler = new_handler;
            }
        }

    };
    function loopy() {

        // Start the polling loop, asynchronously.
        timeout_id = window[str_setTimeout](function () {

            // Iterate over all elements to which the 'resize' event is bound.
            elems.each(function () {
                var elem = $(this),
                        width = elem.width(),
                        height = elem.height(),
                        data = $.data(this, str_data);

                // If element size has changed since the last time, update the element
                // data store and trigger the 'resize' event.
                if (width !== data.w || height !== data.h) {
                    elem.trigger(str_resize, [data.w = width, data.h = height]);
                }

            });

            // Loop.
            loopy();

        }, jq_resize[str_delay]);

    };

})(jQuery, this);

/* ========================================================================
 * ZUI: storeb.js
 * ======================================================================== */
(function (window, $) {
    'use strict';

    var lsName = 'localStorage';
    var storage = window[lsName],
            old = window.store,
            pageName = 'page_' + window.location.pathname + window.location.search;

    /* The Store object */
    var Store = function () {
        this.slience = true;
        this.enable = (lsName in window) && window[lsName] && window[lsName].setItem;
        this.storage = storage;

        this.page = this.get(pageName, {});
    };

    /* Save page data */
    Store.prototype.pageSave = function () {
        if ($.isEmptyObject(this.page)) {
            this.remove(pageName);
        } else {
            var forDeletes = [],
                    i;
            for (i in this.page) {
                var val = this.page[i];
                if (val === null)
                    forDeletes.push(i);
            }
            for (i = forDeletes.length - 1; i >= 0; i--) {
                delete this.page[forDeletes[i]];
            }
            this.set(pageName, this.page);
        }
    };

    /* Remove page data item */
    Store.prototype.pageRemove = function (key) {
        if (typeof this.page[key] != 'undefined') {
            this.page[key] = null;
            this.pageSave();
        }
    };

    /* Clear page data */
    Store.prototype.pageClear = function () {
        this.page = {};
        this.pageSave();
    };

    /* Get page data */
    Store.prototype.pageGet = function (key, defaultValue) {
        var val = this.page[key];
        return(defaultValue !== undefined && (val === null || val === undefined)) ? defaultValue : val;
    };

    /* Set page data */
    Store.prototype.pageSet = function (objOrKey, val) {
        if ($.isPlainObject(objOrKey)) {
            $.extend(true, this.page, objOrKey);
        } else {
            this.page[this.serialize(objOrKey)] = val;
        }
        this.pageSave();
    };

    /* Check enable status */
    Store.prototype.check = function () {
        if (!this.enable) {
            if(!this.slience) throw new Error('Browser not support localStorage or enable status been set true.');
        }
        return this.enable;
    };

    /* Get length */
    Store.prototype.length = function () {
        if (this.check()) {
            return storage.getLength ? storage.getLength() : storage.length;
        }
        return 0;
    };

    /* Remove item with browser localstorage native method */
    Store.prototype.removeItem = function (key) {
        storage.removeItem(key);
        return this;
    };

    /* Remove item with browser localstorage native method, same as removeItem */
    Store.prototype.remove = function (key) {
        return this.removeItem(key);
    };

    /* Get item value with browser localstorage native method, and without deserialize */
    Store.prototype.getItem = function (key) {
        return storage.getItem(key);
    };

    /* Get item value and deserialize it, if value is null and defaultValue been given then return defaultValue */
    Store.prototype.get = function (key, defaultValue) {
        var val = this.deserialize(this.getItem(key));
        if (typeof val === 'undefined' || val === null) {
            if (typeof defaultValue !== 'undefined') {
                return defaultValue;
            }
        }
        return val;
    };

    /* Get item key by index and deserialize it */
    Store.prototype.key = function (index) {
        return storage.key(index);
    };

    /* Set item value with browser localstorage native method, and without serialize filter */
    Store.prototype.setItem = function (key, val) {
        storage.setItem(key, val);
        return this;
    };

    /* Set item value, serialize it if the given value is not an string */
    Store.prototype.set = function (key, val) {
        if(val === undefined) return this.remove(key);
        this.setItem(key, this.serialize(val));
        return this;
    };

    /* Clear all items with browser localstorage native method */
    Store.prototype.clear = function () {
        storage.clear();
        return this;
    };

    /* Iterate all items with callback */
    Store.prototype.forEach = function (callback) {
        for (var i = storage.length - 1; i >= 0; i--) {
            var key = storage.key(i);
            callback(key, this.get(key));
        }
        return this;
    };

    /* Get all items and set value in an object. */
    Store.prototype.getAll = function () {
        var all = {};
        this.forEach(function (key, val) {
            all[key] = val;
        });

        return all;
    };

    /* Serialize value with JSON.stringify */
    Store.prototype.serialize = function (value) {
        if(typeof value === 'string') return value;
        return JSON.stringify(value);
    };

    /* Deserialize value, with JSON.parse if the given value is not a string */
    Store.prototype.deserialize = function (value) {
        if(typeof value !== 'string') return undefined;
        try {
            return JSON.parse(value);
        } catch (e) {
            return value || undefined;
        }
    };

    $.zui({
        store: new Store()
    });
}(window, jQuery));

/* ========================================================================
 * zui-frag.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    $(function () {

        /* 消息提示框 */
        $.zui.setRegional('alertmsg', {
            title: {error: '错误提示', info: '信息提示', warn: '警告信息', correct: '成功信息', confirm: '确认信息'},
            btnMsg: {ok: '确定', yes: '是', no: '否', cancel: '取消'}
        })

        /* dialog */
        $.zui.setRegional('dialog', {
            close: '关闭',
            maximize: '最大化',
            restore: '还原',
            minimize: '最小化',
            title: '弹出窗口'
        })

        /* order by */
        $.zui.setRegional('orderby', {
            asc: '升序',
            desc: '降序'
        })

        /* 分页 */
        $.zui.setRegional('pagination', {
            total: '总记录数/总页数',
            first: '首页',
            last: '末页',
            prev: '上一页',
            next: '下一页',
            page: '页',
            refresh: '刷新'
        })

        $.zui.setRegional('datagrid', {
            asc: '升序',
            desc: '降序',
            showhide: '显示/隐藏 列',
            clear: '清除',
            lock: '锁定列',
            unlock: '解除锁定',
            add: '添加',
            edit: '编辑',
            save: '保存',
            update: '更新',
            cancel: '取消',
            del: '删除',
            enable: '启用',
            disable: '禁用',
            prev: '上一条',
            next: '下一条',
            refresh: '刷新',
            query: '查询',
            'import': '导入',
            'export': '导出',
            all: '全部',
            'true': '是',
            'false': '否',
            noData: '没有数据！',
            expandMsg: '点我展开行！',
            shrinkMsg: '点我收缩行！',
            selectMsg: '未选中任何行！',
            editMsg: '请先保存编辑行！',
            saveMsg: '没有需要保存的行！',
            delMsg: '确定要删除该行吗？',
            delMsgM: '确定要删除选中行？'
        })

        $.zui.setRegional('findgrid', {
            choose: '选择选中项',
            append: '追加选择',
            empty: '清空现有值'
        })

        /* ajax加载提示 */
        $.zui.setRegional(
                'progressmsg', '正在努力加载数据，请稍等...'
                )

        /* navtab右键菜单  */
        $.zui.setRegional('navtabCM', {
            refresh: '刷新本标签',
            close: '关闭本标签',
            closeother: '关闭其他标签',
            closeall: '关闭所有标签'
        })

        /* dialog右键菜单 */
        $.zui.setRegional('dialogCM', {
            refresh: '刷新本窗口',
            close: '关闭本窗口',
            closeother: '关闭其他窗口',
            closeall: '关闭所有窗口'
        })

        /* 503错误提示 */
        $.zui.setRegional('statusCode_503', '服务器当前负载过大或者正在维护！')

        /* AJAX 状态返回 0 提示 */
        $.zui.setRegional('ajaxnosend', '与服务器的通信中断，请检查URL链接或服务器状态！')

        /* timeout提示 */
        $.zui.setRegional('sessiontimeout', '会话超时，请重新登陆！')

        /* 占位符对应选择器无有效值提示 */
        $.zui.setRegional('plhmsg', '占位符对应的选择器无有效值！')

        /* 未定义复选框组名提示 */
        $.zui.setRegional('nocheckgroup', '未定义选中项的组名[复选框的"data-group"]！')

        /* 未选中复选框提示 */
        $.zui.setRegional('notchecked', '未选中任何一项！')

        /* 未选中下拉菜单提示 */
        $.zui.setRegional('selectmsg', '请选择一个选项！')

        /* 表单验证错误提示信息 */
        $.zui.setRegional('validatemsg', '提交的表单中 [{0}] 个字段有错误，请更正后再提交！')

        /* ID检查 */
        $.zui.setRegional('idChecked', '不规范，ID需以字母开头，组成部分包括（0-9，字母，中横线，下划线）')

        /* 框架名称 */
        $.zui.setRegional('uititle', 'ZUI')

        /* 主navtab标题 */
        $.zui.setRegional('maintab', '我的主页')

        /**
         *
         *  Plugins regional setting
         *
         */
    })



    window.FRAG = {
        dialog: '<div class="zui-dialog zui-dialog-container" style="top:150px; left:300px;">' +
                '    <div class="dialogHeader" onselectstart="return false;" oncopy="return false;" onpaste="return false;" oncut="return false;">' +
                '        <a class="close" href="javascript:;" title="#close#"><i class="icon icon-remove-sign"></i></a>' +
                '        <a class="maximize" href="javascript:;" title="#maximize#"><i class="icon icon-plus-sign"></i></a>' +
                '        <a class="restore" href="javascript:;" title="#restore#"><i class="icon icon-history"></i></a>' +
                '        <a class="minimize" href="javascript:;" title="#minimize#"><i class="icon icon-minus-sign"></i></a>' +
                '        <h1><span><i class="icon icon-th-large"></i></span> <span class="title">#title#</span></h1>' +
                '    </div>' +
                '    <div class="dialogContent unitBox"></div>' +
                '    <div class="resizable_h_l" tar="nw"></div>' +
                '    <div class="resizable_h_r" tar="ne"></div>' +
                '    <div class="resizable_h_c" tar="n"></div>' +
                '    <div class="resizable_c_l" tar="w" style="height:100%;"></div>' +
                '    <div class="resizable_c_r" tar="e" style="height:100%;"></div>' +
                '    <div class="resizable_f_l" tar="sw"></div>' +
                '    <div class="resizable_f_r" tar="se"></div>' +
                '    <div class="resizable_f_c" tar="s"></div>' +
                '</div>'
        ,
        splitBar: '<div id="zui-splitBar"></div>',
        splitBarProxy: '<div id="zui-splitBarProxy"></div>',
        resizable: '<div id="zui-resizable" class="zui-resizable"></div>',
        alertBackground: '<div class="zui-alertBackground"></div>',
        maskBackground: '<div class="zui-maskBackground zui-ajax-mask"></div>',
        maskProgress: '<div class="zui-maskProgress zui-ajax-mask"><i class="icon icon-spin icon-spinner"></i>&nbsp;&nbsp;#progressmsg#<div class="progressBg"><div class="progress"></div></div></div>',
        dialogMask: '<div class="zui-dialogBackground"></div>',
        orderby: '<a href="javascript:;" class="order asc" data-order-direction="asc" title="#asc#"><i class="icon icon-chevron-up"></i></a>' +
                '<a href="javascript:;" class="order desc" data-order-direction="desc" title="#desc#"><i class="icon icon-chevron-down"></i></a>'
        ,
        slidePanel: '<div class="panel panel-default">' +
                '    <div class="panel-heading">' +
                '        <h4 class="panel-title"><a data-toggle="collapse" data-parent="#zui-accordionmenu" href="##id#" class="#class#">#icon#&nbsp;#title#<b>#righticon#</b></a></h4>' +
                '    </div>' +
                '    <div id="#id#" class="panel-collapse collapse#bodyclass#">' +
                '        <div class="panel-body">' +
                '        </div>' +
                '    </div>' +
                '</div>'
        ,

        gridPaging: '<ul class="pager">' +
                '    <li class="page-first btn-nav">' +
                '        <a href="javascript:;" title="#first#"><i class="icon icon-step-backward"></i></a>' +
                '    </li>' +
                '    <li class="page-prev btn-nav">' +
                '        <a href="javascript:;" title="#prev#"><i class="icon icon-backward"></i></a>' +
                '    </li>' +
                '    #pageNumFrag#' +
                '    <li class="page-next btn-nav">' +
                '        <a href="javascript:;" title="#next#"><i class="icon icon-forward"></i></a>' +
                '    </li>' +
                '    <li class="page-last btn-nav">' +
                '        <a href="javascript:;" title="#last#"><i class="icon icon-step-forward"></i></a>' +
                '    </li>' +
                '    <li class="page-total">' +
                '        <span title="#total#">#count#</span>' +
                '    </li>' +
                '    <li class="page-reload btn-nav">' +
                '        <a href="javascript:;" title="#refresh#"><i class="icon icon-refresh"></i></a>' +
                '    </li>' +
                '    <select data-toggle="selectpicker"></select>' +
                '</ul>'
        ,
        gridPageNum: '<li class="page-num#active#"><a href="javascript:;">#num#</a></li>',
        gridMenu: '<div class="datagrid-menu-box">'
                + '    <ul>'
                + '        <li class="datagrid-li-asc"><a href="javascript:;"><span class="icon"><i class="icon icon-sort-by-attributes"></i></span><span class="title">#asc#</span></a></li>'
                + '        <li class="datagrid-li-desc"><a href="javascript:;"><span class="icon"><i class="icon icon-sort-by-attributes-alt"></i></span><span class="title">#desc#</span></a></li>'
                + '        <li class="datagrid-li-showhide"><a href="javascript:;"><span class="icon"><i class="icon icon-checked"></i></span><span class="title">#showhide#</span><span class="arrow"></span></a></li>'
                + '        <li class="datagrid-li-lock"><a href="javascript:;"><span class="icon"><i class="icon icon-lock"></i></span><span class="title">#lock#</span></a></li>'
                + '        <li class="datagrid-li-unlock disable"><a href="javascript:;"><span class="icon"><i class="icon icon-unlock-alt"></i></span><span class="title">#unlock#</span></a></li>'
                + '    </ul>'
                + '</div>'
        ,
        gridShowhide: '<li data-index="#index#" class="datagrid-col-check"><a href="javascript:;"><i class="icon icon-checked"></i>#label#</a></li>',
        gridEditBtn: '<button type="button" class="btn btn-success edit"><i class="icon icon-edit"></i> #edit#</button>'
                + '<button type="button" class="btn btn-danger delete"><i class="icon icon-times"></i> #del#</button>'
        ,
        gridExpandBtn: '<span title="#expandMsg#"><i class="icon icon-plus"></i></span>',
        gridShrinkBtn: '<span title="#shrinkMsg#"><i class="icon icon-minus"></i></span>',
        alertBoxFrag: '<div id="zui-alertMsgBox" class="zui-alert"><div class="alertContent"><div class="#type#"><div class="alertInner"><h1>#title#</h1><div class="msg">#message#</div></div><div class="toolBar"><ul>#btnFragment#</ul></div></div></div></div>',
        alertBtnFrag: '<li><button class="btn btn-#class#" rel="#callback#" type="button">#btnMsg#</button></li>',
        navtabCM: '<ul id="zui-navtabCM">' +
                '    <li rel="reload"><span class="icon"><i class="icon icon-refresh"></i></span><span class="title">#refresh#</span></li>' +
                '    <li rel="closeCurrent"><span class="icon"><i class="icon icon-times"></i></span><span class="title">#close#</li>' +
                '    <li rel="closeOther"><span class="icon"><i class="icon icon-times"></i></span><span class="title">#closeother#</li>' +
                '    <li rel="closeAll"><span class="icon"><i class="icon icon-times"></i></span><span class="title">#closeall#</li>' +
                '</ul>'
        ,
        dialogCM: '<ul id="zui-dialogCM">' +
                '    <li rel="reload"><span class="icon"><i class="icon icon-refresh"></i></span><span class="title">#refresh#</span></li>' +
                '    <li rel="closeCurrent"><span class="icon"><i class="icon icon-times"></i></span><span class="title">#close#</span></li>' +
                '    <li rel="closeOther"><span class="icon"><i class="icon icon-times"></i></span><span class="title">#closeother#</span></li>' +
                '    <li rel="closeAll"><span class="icon"><i class="icon icon-times"></i></span><span class="title">#closeall#</span></li>' +
                '</ul>'
    }
}(jQuery);

/* ========================================================================
 * zui-extends.js  v1.3 beta2
 * ======================================================================== */

+function ($) {
    'use strict';

    $.fn.extend({
        /**
         * @param {Object} op: {type:GET/POST, url:ajax请求地址, data:ajax请求参数列表, callback:回调函数 }
         */
        ajaxUrl: function (op) {
            var $this = $(this)
            if(typeof(op)=='string'){
                op = {url:op};
            }
            $this.trigger($.zui.eventType.beforeAjaxLoad)

            if (op.loadingmask) {
                $this.trigger($.zui.eventType.ajaxStatus)
            }

            $.ajax({
                type: op.type || 'GET',
                url: op.url,
                data: op.data || {},
                cache: false,
                dataType: 'html',
                timeout: $.zui.ajaxTimeout,
                success: function (response) {
                    var json = response.toJson(), $ajaxMask = $this.find('> .zui-ajax-mask')
                    if(typeof(response)==='object') {
                        json = response;
                    }
                    if(typeof(response)==='string' && response.substr(0,1)==='"' && response.substr(-1,1)==='"'){
                        response = JSON.parse(response);
                    }
                    if (!json.hasOwnProperty($.zui.keys.status)) {  //不能直接判断有没有code，因为code有可能为0
                        $this.empty().html(response).append($ajaxMask).initui()
                    } else {
                        if (json[$.zui.keys.status] == $.zui.statusCode.error) {
                            if (json[$.zui.keys.message])
                                $this.alertmsg('error', json[$.zui.keys.message])
                            if (!$this.closest('.zui-layout').length) {
                                if ($this.closest('.navtab-panel').length)
                                    $this.navtab('closeCurrentTab')
                                else
                                    $this.dialog('closeCurrent')
                            }
                        }
                        $ajaxMask.fadeOut('normal', function () {
                            $(this).remove()
                        })
                    }

                    if ($.isFunction(op.callback))
                        op.callback(response)
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    $this.zuiajax('ajaxError', xhr, ajaxOptions, thrownError)
                    if (!$this.closest('.zui-layout').length) {
                        if ($this.closest('.navtab-panel').length)
                            $this.navtab('closeCurrentTab')
                        else
                            $this.dialog('closeCurrent')
                    }
                    $this.trigger('zui.ajaxError')
                },
                statusCode: {
                    0: function (xhr, ajaxOptions, thrownError) {
                        $.zui.alertmsg('error', $.zui.regional.ajaxnosend)
                    },
                    503: function (xhr, ajaxOptions, thrownError) {
                        $.zui.alertmsg('error', $.zui.regional.statusCode_503)
                    },
                }
            })
        },
        loadUrl: function (url, data, callback) {
            $(this).ajaxUrl({url: url, data: data, callback: callback})
        },
        doAjax: function (op) {
            var $this = $(this), $target, $ajaxMask;

            if (!op.url) {
                $.zui.debug('The ajax url[doajax] is undefined!');
                return;
            }
            if (!op.callback) {
                $.zui.debug('The ajax callback[doajax] is undefined!');
                //return;
            } else {
                op.callback = op.callback.toFunc();
            }
            if (op.loadingmask) {
                $target = $this.getPageTarget();
                if($target){
                    $target.trigger($.zui.eventType.ajaxStatus);
                    $ajaxMask = $target.find('> .zui-ajax-mask');
                }
            }
            if (!op.type) {
                op.type = 'POST';
            }
            if (!op.dataType) {
                op.dataType = 'json';
            }
            if (!op.cache) {
                op.cache = false;
            }
            op.timeout = op.ajaxTimeout || $.zui.ajaxTimeout;
            op.success = function (response) {
                //检测是否有系统返回的错误信息
                if(response.hasOwnProperty($.zui.keys.status) && response.hasOwnProperty($.zui.keys.message)){
                    status = response[$.zui.keys.status];
                    if(status==$.zui.statusCode.error){
                        $.zui.alertmsg('error', response[$.zui.keys.message]);
                        if(!$target) {
                            $target = $('body').find('div.zui-ajax-mask').parent();
                        }
                        $target.trigger('zui.ajaxStop');
                        return;
                    }
                }

                if ($ajaxMask) {
                    if (op.callback) {
                        $.when(op.callback(response)).done(function () {
                            $target.trigger('zui.ajaxStop')
                        })
                    } else {
                        $target.trigger('zui.ajaxStop')
                    }
                } else {
                    if(op.callback){
                        op.callback(response)
                    }
                }
            }
            op.error = op.error || function (xhr, ajaxOptions, thrownError) {
                $.zui.ajax('ajaxError', xhr, ajaxOptions, thrownError)
                if ($ajaxMask) {
                    $target.trigger('zui.ajaxError')
                }
                if(op.errCallback) {
                    op.errCallback(xhr, ajaxOptions, thrownError)
                }
            }
            op.statusCode = {
                0: function (xhr, ajaxOptions, thrownError) {
                    $.zui.alertmsg('error', $.zui.regional.ajaxnosend)
                },
                503: function (xhr, ajaxOptions, thrownError) {
                    $.zui.alertmsg('error', $.zui.regional.statusCode_503)
                }
            }

            $.ajax(op)
        },
        getPageTarget: function () {
            var $target

            if (this.closest('.zui-layout').length)
                $target = this.closest('.zui-layout')
            else if (this.closest('.navtab-panel').length)
                $target = $.CurrentNavtab
            else if ($('article.article').length)
                $target = $('article.article')
            else
                $target = $.CurrentDialog
            if(!$target) {
                $target = $('body');
            }
            return $target
        },
        resizePageH: function () {
            return this.each(function () {
                //判断是一下是否iframe
                if ($(this).is('iframe')) {
                    $(this).height($(window).height() - $(this).offset().top);
                    return;
                }
                if ($(this).closest('.tab-content').length)
                    return

                var $box = $(this),
                        $pageHeader = $box.find('> .zui-pageHeader'),
                        $pageContent = $box.find('> .zui-pageContent'),
                        $pageFooter = $box.find('> .zui-pageFooter'),
                        headH = $pageHeader.outerHeight() || 0,
                        footH = $pageFooter.outerHeight() || 0

                if($pageContent.length) {
                    if ($pageFooter.css('bottom'))
                        footH += parseInt($pageFooter.css('bottom')) || 0;
                    if (!footH && $box.hasClass('dialogContent'))
                        footH = 5;
                    $pageContent.css({top: headH, bottom: footH});
                    if($pageContent.find('.ps-container').length){
                        $pageContent.css({'overflow':'hidden'});
                    } else {
                        Do.ready('scrollbar', function(){
                            $pageContent.perfectScrollbar();
                        });
                    }
                }
                $(window).trigger($.zui.eventType.resizeGrid)
            })
        },
        getMaxIndexObj: function ($elements) {
            var zIndex = 0, index = 0

            $elements.each(function (i) {
                var newZIndex = parseInt($(this).css('zIndex')) || 1

                if (zIndex < newZIndex) {
                    zIndex = newZIndex
                    index = i
                }
            })

            return $elements.eq(index)
        },
        /**
         * 将表单数据转成JSON对象 用法：$(form).serializeJson() Author: K'naan
         */
        serializeJson: function () {
            var o = {}
            var a = this.serializeArray()

            $.each(a, function () {
                if (o[this.name] !== undefined) {
                    if (!o[this.name].push) {
                        o[this.name] = [o[this.name]]
                    }
                    o[this.name].push(this.value || '')
                } else {
                    o[this.name] = this.value || ''
                }
            })

            return o
        },
        isTag: function (tn) {
            if (!tn)
                return false
            if (!$(this).prop('tagName'))
                return false
            return $(this)[0].tagName.toLowerCase() == tn ? true : false
        },
        /**
         * 判断当前元素是否已经绑定某个事件
         * @param {Object} type
         */
        isBind: function (type) {
            var _events = $(this).data('events')
            return _events && type && _events[type]
        },
        /**
         * 输出firebug日志
         * @param {Object} msg
         */
        log: function (msg) {
            return this.each(function () {
                if (console)
                    console.log('%s: %o', msg, this)
            })
        }
    })

    /**
     * 扩展String方法
     */
    $.extend(String.prototype, {
        isPositiveInteger: function () {
            return (new RegExp(/^[1-9]\d*$/).test(this))
        },
        isInteger: function () {
            return (new RegExp(/^\d+$/).test(this))
        },
        isNumber: function () {
            return (new RegExp(/^([-]{0,1}(\d+)[\.]+(\d+))|([-]{0,1}(\d+))$/).test(this))
        },
        isNormalID: function () {
            return (new RegExp(/^[a-zA-Z][0-9a-zA-Z_-]*$/).test(this))
        },
        includeChinese: function () {
            return (new RegExp(/[\u4E00-\u9FA5]/).test(this))
        },
        trim: function () {
            return this.replace(/(^\s*)|(\s*$)|\r|\n/g, '')
        },
        startsWith: function (pattern) {
            return this.indexOf(pattern) === 0
        },
        endsWith: function (pattern) {
            var d = this.length - pattern.length
            return d >= 0 && this.lastIndexOf(pattern) === d
        },
        replaceSuffix: function (index) {
            return this.replace(/\[[0-9]+\]/, '[' + index + ']').replace('#index#', index)
        },
        replaceSuffix2: function (index) {
            return this.replace(/\-(i)([0-9]+)$/, '-i' + index).replace('#index#', index)
        },
        trans: function () {
            return this.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"')
        },
        encodeTXT: function () {
            return (this).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll(' ', '&nbsp;')
        },
        replaceAll: function (os, ns) {
            return this.replace(new RegExp(os, 'gm'), ns)
        },
        /*替换占位符为对应选择器的值*/ //{^(.|\#)[A-Za-z0-9_-\s]*}
        replacePlh: function ($box) {
            $box = $box || $(document)
            return this.replace(/{\/?[^}]*}/g, function ($1) {
                var $input = $box.find($1.replace(/[{}]+/g, ''))

                return $input && $input.val() ? $input.val() : $1
            })
        },
        replaceMsg: function (holder) {
            return this.replace(new RegExp('({.*})', 'g'), holder)
        },
        replaceTm: function ($data) {
            if (!$data)
                return this

            return this.replace(RegExp('({[A-Za-z_]+[A-Za-z0-9_-]*})', 'g'), function ($1) {
                return $data[$1.replace(/[{}]+/g, '')]
            })
        },
        replaceTmById: function (_box) {
            var $parent = _box || $(document)

            return this.replace(RegExp('({[A-Za-z_]+[A-Za-z0-9_-]*})', 'g'), function ($1) {
                var $input = $parent.find('#' + $1.replace(/[{}]+/g, ''))
                return $input.val() ? $input.val() : $1
            })
        },
        isFinishedTm: function () {
            return !(new RegExp('{\/?[^}]*}').test(this))
        },
        skipChar: function (ch) {
            if (!this || this.length === 0)
                return ''
            if (this.charAt(0) === ch)
                return this.substring(1).skipChar(ch)
            return this
        },
        isValidPwd: function () {
            return (new RegExp(/^([_]|[a-zA-Z0-9]){6,32}$/).test(this))
        },
        isValidMail: function () {
            return(new RegExp(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(this.trim()))
        },
        isSpaces: function () {
            for (var i = 0; i < this.length; i += 1) {
                var ch = this.charAt(i)

                if (ch != ' ' && ch != '\n' && ch != '\t' && ch != '\r')
                    return false
            }
            return true
        },
        isPhone: function () {
            return (new RegExp(/(^([0-9]{3,4}[-])?\d{3,8}(-\d{1,6})?$)|(^\([0-9]{3,4}\)\d{3,8}(\(\d{1,6}\))?$)|(^\d{3,8}$)/).test(this))
        },
        isUrl: function () {
            return (new RegExp(/^[a-zA-z]+:\/\/([a-zA-Z0-9\-\.]+)([-\w .\/?%&=:]*)$/).test(this))
        },
        isExternalUrl: function () {
            return this.isUrl() && this.indexOf('://' + document.domain) == -1
        },
        toBool: function () {
            return (this.toLowerCase() === 'true') ? true : false
        },
        toJson: function () {
            var json = this

            try {
                if (typeof json === 'object')
                    json = json.toString()
                if (!json.trim().match("^\{(.+:.+,*){1,}\}$"))
                    return this
                else
                    return JSON.parse(this)
            } catch (e) {
                return this
            }
        },
        toObj: function () {
            var obj = null

            try {
                obj = (new Function('return ' + this))()
            } catch (e) {
                obj = this
                $.zui.debug('String toObj：Parse "String" to "Object" error! Your str is: ' + this)
            }
            return obj
        },
        /**
         * String to Function
         * 参数(方法字符串或方法名)： 'function(){...}' 或 'getName' 或 'USER.getName' 均可
         * Author: K'naan
         */
        toFunc: function () {
            if (!this || !this.length)
                return undefined

            if (this.startsWith('function')) {
                return (new Function('return ' + this))()
            }

            try {
                var m_arr = this.split('.'), fn = window

                for (var i = 0; i < m_arr.length; i++) {
                    fn = fn[m_arr[i]]
                }

                if (typeof fn === 'function') {
                    return fn
                }
            } catch (e) {
                return undefined
            }
        }
    })

    /* Function */
    $.extend(Function.prototype, {
        //to fixed String.prototype -> toFunc
        toFunc: function () {
            return this
        }
    })

    /* Global */
    $.isJson = function (obj) {
        var flag = true

        try {
            flag = $.parseJSON(obj)
        } catch (e) {
            return false
        }
        return flag ? true : false
    }
    $.isExitsFunction = function (funcName) {
        try {
            if (typeof (eval(funcName)) == "function") {
                return true;
            }
        } catch (e) {
        }
        return false;
    };
    $.isString = function (varName){
        return typeof(varName)==='string';
    };
    $.isObject = function (varName){
        return typeof(varName)==='object';
    };
}(jQuery);

/* ========================================================================
 * zui-initui.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    // INITUI CLASS DEFINITION
    // ======================
    var Initui = function (element, options) {
        var $this = this
        this.$element = $(element)
        this.options = options
    }

    Initui.DEFAULTS = {}

    Initui.prototype.init = function () {
        var that = this, $element = that.$element;

        $.when(that.initUI()).done(function () {
            $element.trigger($.zui.eventType.afterInitUI)
        })
    }

    Initui.prototype.initUI = function () {
        var $element = this.$element;

        $.when($element.trigger($.zui.eventType.beforeInitUI)).done(function () {
            $element.trigger($.zui.eventType.initUI)
        })
    }

    // INITUI PLUGIN DEFINITION
    // =======================

    function Plugin(option) {
        var args = arguments,
                property = option

        return this.each(function () {
            var $this = $(this),
                    options = $.extend({}, Initui.DEFAULTS, $this.data(), typeof option === 'object' && option),
                    data = $this.data('zui.initui')

            if (!data)
                $this.data('zui.initui', (data = new Initui(this, options)))

            if (typeof property === 'string' && $.isFunction(data[property])) {
                [].shift.apply(args)
                if (!args)
                    data[property]()
                else
                    data[property].apply(data, args)
            } else {
                data.init()
            }
        })
    }

    var old = $.fn.initui

    $.fn.initui = Plugin
    $.fn.initui.Constructor = Initui

    // INITUI NO CONFLICT
    // =================

    $.fn.initui.noConflict = function () {
        $.fn.initui = old
        return this
    }

    // INITUI DATA-API
    // ==============

    $(document).on('click.zui.initui.data-api', '[data-toggle="initui"]', function (e) {
        Plugin.call($this, $this.data())

        e.preventDefault()
    })

    /* beforeInitUI */
    $(document).on($.zui.eventType.beforeInitUI, function (e) {
        var $box = $(e.target),noinits = [],$noinit = $box.find('[data-noinit]');

        //progress
        $box.find('> .zui-maskProgress').find('.progress').stop().animate({width: '85%'}, 'fast');

        // Hide not need to initialize the UI DOM
        $noinit.each(function (i) {
            var $this = $(this),pos = {};

            pos.$target = $this;
            pos.$next = $this.next();
            pos.$prev = $this.prev();
            pos.$parent = $this.parent();
            pos.visible = $this.is(':visible') ? true : false;

            noinits.push(pos);
            $this.remove();
        });

        $box.data('zui.noinit', noinits);
    })

    /* initUI */
    $(document).on($.zui.eventType.initUI, function (e) {
        var $box = $(e.target);

        //progress
        $box.find('> .zui-maskProgress').find('.progress').stop().animate({width: '95%'}, 'fast');
    })

    /* afterInitUI */
    $(document).on($.zui.eventType.afterInitUI, function (e) {
        var $box = $(e.target),noinits = $box.data('zui.noinit'),$form = $box.find('> .zui-pageContent').find('form')

        // Recovery not need to initialize the UI DOM
        if (noinits) {
            $.each(noinits, function (i, n) {
                if (n.$next.length)
                    n.$next.before(n.$target)
                else if (n.$prev.length)
                    n.$prev.after(n.$target)
                else if (n.$parent.length)
                    n.$parent.append(n.$target)

                if (n.visible)
                    n.$target.show()

                $box.removeData('zui.noinit')
            })
        }

        /* resizePageH */
        $box.resizePageH()

        //submit
        if ($form.length) {
            $box.find('> .zui-pageFooter').find(':submit').on('click.zui.submit', function (e) {
                e.preventDefault()

                $form.submit()
            })
        }

        //progress
        $box.find('> .zui-maskProgress').find('.progress').stop().animate({width: '100%'}, 'fast', function () {
            $box.find('> .zui-ajax-mask').fadeOut('normal', function () {
                $(this).remove()
            })
        })
    })

    /* Lateral Navigation */
    $(document).one($.zui.eventType.afterInitUI, function (e) {
        var $hnavbar = $('#zui-hnav-navbar'), $active = $hnavbar.find('> li.active')

        if ($active.length && $active.find('> .items').length) {
            $active.find('> a').trigger('click')
        }
    })

    /* ajaxStatus */
    var zui_ajaxStatus = function ($target) {
        var $this = $target,$offset = $this,position = $this.css('position');
        if (position == 'static')
            $offset = $this.offsetParent()

        var zIndex = parseInt($offset.css('zIndex')) || 0
        var $ajaxBackground = $this.find('> .zui-maskBackground')
        var $ajaxProgress = $this.find('> .zui-maskProgress')
        if($target[0].nodeName==='BODY') {
            return {$bg: $ajaxBackground, $pr: $ajaxProgress}
        }

        if (!$ajaxBackground.length && !$ajaxProgress.length) {
            $ajaxBackground = $(FRAG.maskBackground)
            $ajaxProgress   = $($.zui.doRegional(FRAG.maskProgress, $.zui.regional))
            $this.prepend($ajaxBackground).prepend($ajaxProgress)
        }

        //兼容一下iframe页面中的显示位置
        //var _Top = $(window).scrollTop();
        //$ajaxProgress.css({top: _Top+($(window).height()-$ajaxProgress.outerHeight())/2});
        //$ajaxBackground.css({top: _Top+($(window).height()-$ajaxProgress.outerHeight())/2});

        //var bgZindex = parseInt($ajaxBackground.css('zIndex')) || 0
        //var prZindex = parseInt($ajaxProgress.css('zIndex')) || 0

        $ajaxBackground.css('zIndex', zIndex + 100000)
        $ajaxProgress.css('zIndex', zIndex + 100001)

        return {$bg: $ajaxBackground, $pr: $ajaxProgress}
    }

    //显示AJAX加载动画，如何确保同一个页面只有一个加载动画？
    $(document)
            .on('zui.ajaxStart', function (e, timeout, callback) {
                var ajaxMask = zui_ajaxStatus($(e.target))

                ajaxMask.$bg.fadeIn()
                ajaxMask.$pr.fadeIn()
                ajaxMask.$pr.find('.progress').animate({width: '80%'}, timeout || 500)

                if (callback) {
                    setTimeout(function () {
                        callback.toFunc().call(this)
                    }, 25)
                }
            })
            .on('zui.ajaxStop', function (e) {
                var ajaxMask = zui_ajaxStatus($(e.target))

                ajaxMask.$pr.find('.progress').animate({width: '100%'}, 'fast', function () {
                    ajaxMask.$bg.remove()
                    ajaxMask.$pr.remove()
                })
            })
            .on('zui.ajaxError', function (e) {
                var ajaxMask = zui_ajaxStatus($(e.target))

                ajaxMask.$bg.remove()
                ajaxMask.$pr.remove()
            })

    $(document).on($.zui.eventType.ajaxStatus, function (e) {
        var $target = $(e.target), ajaxMask = zui_ajaxStatus($target)

        $target
                .one('ajaxStart', function () {
                    ajaxMask.$bg.fadeIn()
                    ajaxMask.$pr.fadeIn()

                    ajaxMask.$pr.find('.progress').animate({width: '10%'}, 'fast')
                })
                .one('ajaxStop', function () {
                    ajaxMask.$bg.fadeOut()
                    ajaxMask.$pr.fadeOut()
                    ajaxMask.$pr.find('.progress').animate({width:'80%'}, 'fast')
                })
                .one('ajaxError', function () {
                    ajaxMask.$bg.remove()
                    ajaxMask.$pr.remove()
                })
    })

    /* Clean plugins generated 'Dom elements' in the body */
    var bodyClear = function ($target) {
    }

    $(document).on($.zui.eventType.beforeLoadDialog, function (e) {

    }).on($.zui.eventType.beforeAjaxLoad, function (e) {
        bodyClear($(e.target))
    }).on($.zui.eventType.beforeCloseNavtab, function (e) {
        bodyClear($(e.target))
    }).on($.zui.eventType.beforeCloseDialog, function (e) {
        bodyClear($(e.target))
    })

    /* other */
    $(function () {
        $(document).on('keydown keyup', function (e) {
            if (e.which === $.zui.keyCode.CTRL) {
                $.zui.KeyPressed.ctrl = e.type == 'keydown' ? true : false
            }
            if (e.which === $.zui.keyCode.SHIFT) {
                $.zui.KeyPressed.shift = e.type == 'keydown' ? true : false
            }
        })
    })
}(jQuery);

/* ========================================================================
 * zui-theme.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    // THEME GLOBAL ELEMENTS
    // ======================

    var $themeLink, $themeLis

    $(function () {
        var INIT_THEME = function () {
            $themeLink = $('#zui-link-theme')
            $themeLis = $('#zui-themes')
            if ($.cookie) {
                var themeName = $.cookie('zui_theme') || 'green'
                var $li = $themeLis.find('a.theme_' + themeName)
                $li.theme({})
            }
        }

        INIT_THEME()
    })

    // THEME CLASS DEFINITION
    // ======================
    var Theme = function (element, options) {
        this.$element = $(element)
        this.options = options
    }

    Theme.DEFAULTS = {
        theme: 'purple'
    }

    Theme.prototype.init = function () {
        if (!$themeLink.length)
            return
        var themeHref = $themeLink.attr('href')

        themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
        themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
        themeHref += '/' + this.options.theme + '/core.css'
        $themeLink.attr('href', themeHref)

        var $themeA = this.$element.closest('ul').prev()
        var classA = $themeA.attr('class')

        classA = classA.replace(/(theme[\s][a-z]*)/g, '')
        $themeA.removeClass().addClass(classA).addClass('theme').addClass(this.options.theme)
        $themeLis.find('li').removeClass('active')
        this.$element.parent().addClass('active')
        this.cookie()
    }

    Theme.prototype.setTheme = function (themeName, force) {
        if (force) {
            this.options.theme = themeName;
            var themeHref = $themeLink.attr('href')

            themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
            themeHref = themeHref.substring(0, themeHref.lastIndexOf('/'))
            themeHref += '/' + themeName + '/core.css'
            $themeLink.attr('href', themeHref)
            this.cookie();
        } else {
            $themeLis.find('a.theme_' + themeName).trigger('click')
        }
    }

    Theme.prototype.cookie = function () {
        var theme = this.options.theme

        if ($.cookie)
            $.cookie('zui_theme', theme, {path: '/', expires: 30});
    }

    // THEME PLUGIN DEFINITION
    // =======================

    function Plugin(option) {
        var args = arguments
        var property = option

        return this.each(function () {
            var $this = $(this)
            var options = $.extend({}, Theme.DEFAULTS, $this.data(), typeof option === 'object' && option)
            var data = $this.data('zui.theme')

            if (!data)
                $this.data('zui.theme', (data = new Theme(this, options)))
            if (typeof property === 'string' && $.isFunction(data[property])) {
                [].shift.apply(args)
                if (!args)
                    data[property]()
                else
                    data[property].apply(data, args)
            } else {
                data.init()
            }
        })
    }

    var old = $.fn.theme

    $.fn.theme = Plugin
    $.fn.theme.Constructor = Theme

    // THEME NO CONFLICT
    // =================

    $.fn.theme.noConflict = function () {
        $.fn.theme = old
        return this
    }

    // THEME DATA-API
    // ==============

    $(document).on('click.zui.theme.data-api', '[data-toggle="theme"]', function (e) {
        Plugin.call($(this))

        e.preventDefault()
    })
}(jQuery);

/* ========================================================================
 * zui-contextmenu.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    // CONTEXTMENU GLOBAL ELEMENTS
    // ======================

    var $menu, $shadow, hash

    $(function () {
        var INIT_CONTEXTMENU = function () {
            $menu = $('<div id="zui-contextmenu"></div>').hide()
            $shadow = $('<div id="zui-contextmenuShadow"></div>').hide()
            hash = []

            $('body').append('<!-- contextmenu -->').append($menu).append($shadow)
        }

        INIT_CONTEXTMENU()
    })

    // CONTEXTMENU CLASS DEFINITION
    // ======================
    var Contextmenu = function (element, options) {
        this.$element = $(element)
        this.options = options
    }

    Contextmenu.DEFAULTS = {
        id: undefined,
        shadow: true,
        bindings: {},
        ctrSub: null
    }

    Contextmenu.prototype.init = function () {
        var that = this
        var op = this.options

        if (!op.id)
            return
        hash.push({
            id: op.id,
            shadow: op.shadow,
            bindings: op.bindings || {},
            ctrSub: op.ctrSub
        })

        var index = hash.length - 1

        this.$element.on('contextmenu', function (e) {
            that.display(index, this, e, op)
            return false
        })
    }

    Contextmenu.prototype.display = function (index, trigger, e, options) {
        var that = this
        var cur = hash[index]
        var cp = $.zui.regional[cur.id]
        var content = FRAG[cur.id]

        $.each(cp, function (i, n) {
            content = content.replace('#' + i + '#', cp[i])
        })

        // Send the content to the menu
        $menu.html(content)
        $.each(cur.bindings, function (id, func) {
            $('[rel="' + id + '"]', $menu).on('click', function (e) {
                that.hide()
                func($(trigger), $('#zui-' + cur.id))
            })
        })

        var posX = e.pageX
        var posY = e.pageY

        if ($(window).width() < posX + $menu.width())
            posX -= $menu.width()
        if ($(window).height() < posY + $menu.height())
            posY -= $menu.height()

        $menu.css({'left': posX, 'top': posY}).show()
        if (cur.shadow)
            $shadow.css({width: $menu.width(), height: $menu.height(), left: posX + 3, top: posY + 3}).show()
        $(document).one('click', that.hide)

        if ($.isFunction(cur.ctrSub))
            cur.ctrSub($(trigger), $('#zui-' + cur.id))
    }

    Contextmenu.prototype.hide = function () {
        $menu.hide()
        $shadow.hide()
    }

    /* Custom contextmenu */
    Contextmenu.prototype.show = function (options) {
        var that = this

        if (options.items && options.items.length) {
            that.$element.on('contextmenu', function (e) {
                var isShow = true

                /*exclude*/
                if (options.exclude) {
                    that.$element.find(options.exclude).each(function () {
                        if (this == e.target || $(this).find(e.target).length) {
                            isShow = false
                            return
                        }
                    })
                }

                if (!isShow) {
                    e.stopPropagation()
                    return !isShow
                } else {
                    that.custom(options.items, e)
                }

                return false
            })
        }
    }

    Contextmenu.prototype.custom = function (items, e) {
        $menu.empty().html('<ul></ul>')

        var that = this
        var options = that.options
        var $ul = $menu.find('> ul'), $li

        $.each(items, function (i, n) {
            var icon = ''
            if(n.hasOwnProperty('skip') && n.skip) {

            } else {
                if (n.icon)
                    icon = '<i class="icon icon-' + n.icon + '"></i>'
                if (n.title == 'diver') {
                    $li = $('<li class="diver"></li>')
                } else {
                    $li = $('<li><span class="icon">' + icon + '</span><span class="title">' + n.title + '</span></li>')
                    if (n.func && typeof n.func === 'string')
                        n.func = n.func.toFunc()
                    if (n.func) {
                        $li.on('click', function (evt) {
                            that.hide()
                            n.func(that.$element, $li)
                        })
                    }
                }
                $li.appendTo($ul)
            }
        })

        var posX = e.pageX
        var posY = e.pageY

        if ($(window).width() < posX + $menu.width())
            posX -= $menu.width()
        if ($(window).height() < posY + $menu.height())
            posY -= $menu.height()

        $menu.css({'left': posX, 'top': posY}).show()

        if (options.shadow)
            $shadow.css({width: $menu.width(), height: $menu.height(), left: posX + 3, top: posY + 3}).show()

        $(document).one('click', that.hide)
    }

    // CONTEXTMENU PLUGIN DEFINITION
    // =======================

    function Plugin(option) {
        var args = arguments
        var property = option

        return this.each(function () {
            var $this = $(this)
            var options = $.extend({}, Contextmenu.DEFAULTS, $this.data(), typeof option === 'object' && option)
            var data = $this.data('zui.contextmenu')

            if (!data)
                $this.data('zui.contextmenu', (data = new Contextmenu(this, options)))
            if (typeof property === 'string' && $.isFunction(data[property])) {
                [].shift.apply(args)
                if (!args)
                    data[property]()
                else
                    data[property].apply(data, args)
            } else {
                data.init()
            }
        })
    }

    var old = $.fn.contextmenu

    $.fn.contextmenu = Plugin
    $.fn.contextmenu.Constructor = Contextmenu

    // CONTEXTMENU NO CONFLICT
    // =================

    $.fn.contextmenu.noConflict = function () {
        $.fn.contextmenu = old
        return this
    }

}(jQuery);

/* ========================================================================
 * zui-navtab.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    // NAVTAB GLOBAL ELEMENTS
    // ======================

    var currentIndex, $currentTab, $currentPanel, $box, $tabs, $panels, $prevBtn, $nextBtn, $moreBtn, $moreBox, $main, $mainLi,
            autorefreshTimer


    // NAVTAB CLASS DEFINITION
    // ======================

    var Navtab = function (options) {
        this.options = options
        this.tools = this.TOOLS()
    }

    Navtab.DEFAULTS = {
        id: null,
        title: 'New tab',
        url: null,
        type: 'GET',
        data: {},
        loadingmask: true,
        fresh: false,
        autorefresh: false,
        onLoad: null,
        beforeClose: null,
        onClose: null,
        external: false, //是否以框架形式加载
    }

    $(function () {
        var INIT_NAVTAB = function () {
            currentIndex = 0
            $box = $('#zui-navtab')
            $tabs = $box.find('.navtab-tab')
            $panels = $box.find('.navtab-panel')
            $prevBtn = $box.find('.tabsLeft')
            $nextBtn = $box.find('.tabsRight')
            $moreBtn = $box.find('.tabsMore')
            $moreBox = $box.find('.tabsMoreList')
            $main = $tabs.find('li:first')
            $mainLi = $moreBox.find('li:first')

            $prevBtn.click(function () {
                $(this).navtab('scrollPrev')
            })
            $nextBtn.click(function () {
                $(this).navtab('scrollNext')
            })
            $moreBtn.click(function () {
                $moreBox.show()
            })

            $(document).on('click.zui.navtab.switchtab', function (e) {
                var $target = e.target.tagName == 'I' ? $(e.target).parent() : $(e.target)

                if ($moreBtn[0] != $target[0])
                    $moreBox.hide()
            })

            var mainTit, options

            $main
                // .navtab('contextmenu', $main)
                .click(function () {
                    if (!$(this).hasClass('active'))
                        $(this).navtab('switchTab', 'main')
                })
                .find('> a > span').html(function (n, c) {
                    return (mainTit = c.replace('#maintab#', $.zui.regional.maintab))
                })

            options = $.extend({}, Navtab.DEFAULTS, $main.data(), {id: 'main', title: mainTit})

            $main.data('options', $.extend({}, options))

            if ($main.attr('data-url')) {
                $(document).one($.zui.eventType.initUI, function (e) {
                    $main.removeAttr('data-url').navtab('reload', options)
                })
            }

            setTimeout(function () {
                $mainLi.trigger('click')
            }, 100)

            $mainLi
                    .click(function () {
                        if ($(this).hasClass('active'))
                            $moreBox.hide()
                        else
                            $(this).navtab('switchTab', 'main')
                    })
                    .find('> a').html(function (n, c) {
                return c.replace('#maintab#', $.zui.regional.maintab)
            })
        }

        INIT_NAVTAB()
    })

    Navtab.prototype.TOOLS = function () {
        var that = this
        var tools = {
            getDefaults: function () {
                return Navtab.DEFAULTS
            },
            getTabs: function () {
                return $tabs.find('> li')
            },
            getPanels: function () {
                return $panels.find('> div')
            },
            getMoreLi: function () {
                return $moreBox.find('> li')
            },
            getTab: function (tabid) {
                var index = this.indexTabId(tabid)

                if (index >= 0)
                    return this.getTabs().eq(index)
            },
            getPanel: function (tabid) {
                var index = this.indexTabId(tabid)

                if (index >= 0)
                    return this.getPanels().eq(index)
            },
            getTabsW: function (iStart, iEnd) {
                return this.tabsW(this.getTabs().slice(iStart, iEnd))
            },
            tabsW: function ($tabs) {
                var iW = 0

                $tabs.each(function () {
                    iW += $(this).outerWidth(true)
                })

                return iW
            },
            indexTabId: function (tabid) {
                var iOpenIndex = -1

                if (!tabid)
                    return iOpenIndex

                this.getTabs().each(function (index) {
                    if ($(this).data('options').id == tabid) {
                        iOpenIndex = index
                        return false
                    }
                })

                return iOpenIndex
            },
            getLeft: function () {
                return $tabs.position().left
            },
            getScrollBarW: function () {
                return $box.width() - 55
            },
            visibleStart: function () {
                var $tabs = this.getTabs(), iLeft = this.getLeft(), iW = 0, index = 0

                $tabs.each(function (i) {
                    if (iW + iLeft >= 0) {
                        index = i
                        return false
                    }
                    iW += $(this).outerWidth(true)
                })

                return index
            },
            visibleEnd: function () {
                var tools = this, $tabs = this.getTabs(), iLeft = this.getLeft(), iW = 0, index = $tabs.length

                $tabs.each(function (i) {
                    iW += $(this).outerWidth(true)
                    if (iW + iLeft > tools.getScrollBarW()) {
                        index = i
                        return false
                    }
                })

                return index
            },
            scrollPrev: function () {
                var iStart = this.visibleStart()

                if (iStart > 0)
                    this.scrollTab(-this.getTabsW(0, iStart - 1))
            },
            scrollNext: function () {
                var iEnd = this.visibleEnd()

                if (iEnd < this.getTabs().size())
                    this.scrollTab(-this.getTabsW(0, iEnd + 1) + this.getScrollBarW())
            },
            scrollTab: function (iLeft, isNext) {
                $tabs.animate({left: iLeft}, 150, function () {
                    that.tools.ctrlScrollBtn()
                })
            },
            scrollCurrent: function () { // auto scroll current tab
                var iW = this.tabsW(this.getTabs()), scrollW = this.getScrollBarW()
                if (currentIndex==0 || iW <= scrollW)
                    this.scrollTab(0)
                else if (this.getLeft() < scrollW - iW)
                    this.scrollTab(scrollW - iW)
                else if (currentIndex < this.visibleStart())
                    this.scrollTab(-this.getTabsW(0, currentIndex))
                else if (currentIndex >= this.visibleEnd())
                    this.scrollTab(scrollW - this.getTabs().eq(currentIndex).outerWidth(true) - this.getTabsW(0, currentIndex))
            },
            ctrlScrollBtn: function () {
                var iW = this.tabsW(this.getTabs())

                if (this.getScrollBarW() > iW) {
                    $prevBtn.hide()
                    $nextBtn.hide()
                    $tabs.parent().removeClass('tabsPageHeaderMargin')
                } else {
                    $prevBtn.show().removeClass('tabsLeftDisabled')
                    $nextBtn.show().removeClass('tabsRightDisabled')
                    $tabs.parent().addClass('tabsPageHeaderMargin')
                    if (this.getLeft() >= 0)
                        $prevBtn.addClass('tabsLeftDisabled')
                    else if (this.getLeft() <= this.getScrollBarW() - iW)
                        $nextBtn.addClass('tabsRightDisabled')
                }
            },
            switchTab: function (iTabIndex) {
                var $tab = this.getTabs().removeClass('active').eq(iTabIndex).addClass('active'), $panels = this.getPanels(), $panel = $panels.eq(iTabIndex), onSwitch = that.options.onSwitch ? that.options.onSwitch.toFunc() : null
                var $ajaxBackground = $(FRAG.maskBackground)

                $panels.css({top: '-10000000px'})

                if ($tab.data('reloadFlag')) {
                    $panel.animate({top: 0})
                    that.refresh($tab.data('options').id)
                } else {
                    if ($panel.find('.zui-ajax-mask').length) {
                        $panel.css({top: 0})
                    } else {
                        $panel
                                .css({top: 0})
                                .append($ajaxBackground)

                        $ajaxBackground.fadeOut('normal', function () {
                            $(this).remove()
                        })
                    }
                }

                this.getMoreLi().removeClass('active').eq(iTabIndex).addClass('active')
                currentIndex = iTabIndex
                this.scrollCurrent()
                $currentTab = $tab
                $.CurrentNavtab = $currentPanel = $panel

                if (onSwitch)
                    onSwitch.apply(that)

                // set current to body data
                var datas = $('body').data('zui.navtab')

                if (!that.options.id)
                    $.extend(that.options, $tab.data('options')) // for main
                datas.current = that

                // events
                $panel.trigger('zui.navtab.switch')
            },
            closeTab: function (index, openTabid) {
                var $tab = this.getTabs().eq(index),
                        $more = this.getMoreLi().eq(index),
                        $panel = this.getPanels().eq(index),
                        options = $tab.data('options'),
                        beforeClose = options.beforeClose ? options.beforeClose.toFunc() : null,
                        onClose = options.onClose ? options.onClose.toFunc() : null,
                        canClose = true

                if (beforeClose)
                    canClose = beforeClose.apply(that, [$panel])
                if (!canClose) {
                    that.tools.switchTab(index)
                    return
                }
                $tab.remove()
                $more.remove()
                $panel.trigger($.zui.eventType.beforeCloseNavtab).remove()

                if (autorefreshTimer)
                    clearInterval(autorefreshTimer)
                if (onClose)
                    onClose.apply(that)
                if (currentIndex >= index)
                    currentIndex--
                if (openTabid) {
                    var openIndex = this.indexTabId(openTabid)

                    if (openIndex > 0)
                        currentIndex = openIndex
                }

                // remove from body
                var datas = $('body').data('zui.navtab')

                if (datas[options.id])
                    delete datas[options.id]

                this.scrollCurrent()
                this.switchTab(currentIndex)
            },
            closeOtherTab: function (index) {
                index = index || currentIndex

                this.getTabs().each(function (i) {
                    if (i > 0 && index != i)
                        $(this).find('> .close').trigger('click')
                })
            },
            loadUrlCallback: function ($panel) {
                $panel.find(':button.btn-close').click(function () {
                    that.closeCurrentTab()
                })
            },
            updateTit: function (index, title) {
                this.getTabs().eq(index).find('> a').attr('title', title.trim()).find('> span').html(title)
                this.getMoreLi().eq(index).find('> a').attr('title', title.trim()).html(title)
            },
            reload: function ($tab, flag) {
                flag = flag || $tab.data('reloadFlag')

                var options = $tab.data('options')

                if (flag) {
                    $tab.data('reloadFlag', false)
                    var $panel = that.tools.getPanel(options.id)

                    if ($tab.hasClass('external')) {
                        that.openExternal(options.url, $panel, options.data)
                    } else {
                        that.tools.reloadTab($panel, options)
                    }
                }
            },
            reloadTab: function ($panel, options) {
                var onLoad = options.onLoad ? options.onLoad.toFunc() : null,
                        arefre = options.autorefresh && (isNaN(String(options.autorefresh)) ? 15 : options.autorefresh)
                if(!$panel) return;
                $panel
                        .trigger($.zui.eventType.beforeLoadNavtab)
                        .ajaxUrl({
                            type: (options.type || 'GET'),
                            url: options.url,
                            data: options.data || {},
                            loadingmask: options.loadingmask,
                            callback: function (response) {
                                that.tools.loadUrlCallback($panel)
                                if (onLoad)
                                    onLoad.apply(that, [$panel])
                                if (autorefreshTimer)
                                    clearInterval(autorefreshTimer)
                                if (arefre)
                                    autorefreshTimer = setInterval(function () {
                                        $panel.navtab('refresh')
                                    }, arefre * 1000)
                                if ($.zui.ui.clientPaging && $panel.data('zui.clientPaging'))
                                    $panel.pagination('setPagingAndOrderby', $panel)
                            }
                        })
            }
        }

        return tools
    }

    Navtab.prototype.contextmenu = function ($obj) {
        var that = this

        $obj.contextmenu({
            id: 'navtabCM',
            bindings: {
                reload: function (t, m) {
                    if (t.data('options').url)
                        that.refresh(t.data('options').id)
                },
                closeCurrent: function (t, m) {
                    var tabId = t.data('options').id

                    if (tabId)
                        that.closeTab(tabId)
                    else
                        that.closeCurrentTab()
                },
                closeOther: function (t, m) {
                    if (!t.index()) {
                        that.closeAllTab()
                    } else {
                        var index = that.tools.indexTabId(t.data('options').id)

                        that.tools.closeOtherTab(index > 0 ? index : currentIndex)
                    }
                },
                closeAll: function (t, m) {
                    that.closeAllTab()
                }
            },
            ctrSub: function (t, m) {
                var mReload = m.find('[rel="reload"]'),
                        mCur = m.find('[rel="closeCurrent"]'),
                        mOther = m.find('[rel="closeOther"]'),
                        mAll = m.find('[rel="closeAll"]'),
                        $tabLi = that.tools.getTabs()

                if (!t.index()) {
                    mCur.addClass('disabled')
                    if (!t.data('options').url)
                        mReload.addClass('disabled')
                }
            }
        })
    }

    // if found tabid replace tab, else create a new tab.
    Navtab.prototype.openTab = function () {
        var that = this, options = this.options, tools = this.tools, iOpenIndex

        if (!options.url && options.href)
            options.url = options.href
        if(options.title) {
            options.title = options.title.trim();
        }

        if (!options.url) {
            $.zui.debug('Navtab Plugin: Error trying to open a navtab, url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh()

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('Navtab Plugin: The new navtab\'s url is incorrect, url: ' + options.url)
                return
            }

            options.url = encodeURI(options.url)
        }

        iOpenIndex = options.id ? tools.indexTabId(options.id) : currentIndex

        if (iOpenIndex >= 0) {
            var $tab = tools.getTabs().eq(iOpenIndex),
                    $panel = tools.getPanels().eq(iOpenIndex),
                    op = $tab.data('options')

            var sss = $panel.find('iframe').first().prop('contentWindow');
            var openurl = '';
            if(typeof(sss)==='object' && sss.hasOwnProperty('document')){
                openurl = sss.document.location.href.replace(sss.location.origin, '');
            }

            if (options.fresh || options.url != op.url || (openurl&&options.url != openurl)) {
                Do.ready('tips', function () {
                    toastr.info('页面重新加载中，请稍候......');
                });
                that.reload(options)
            } else if (options.title != op.title) {
                op.title = options.title
                tools.updateTit(iOpenIndex, options.title)
            }

            currentIndex = iOpenIndex

            if (options.id == 'main') {
                this.contextmenu($tab)
            }
        } else {
            var tabFrag = '<li><a href="javascript:" title="#title#"><span>#title#</span></a><span class="close">&times;</span></li>',
                    $tab = $(tabFrag.replaceAll('#title#', options.title)),
                    $panel = $('<div class="navtabPage unitBox"></div>'),
                    $more = $('<li><a href="javascript:" title="#title#">#title#</a></li>'.replaceAll('#title#', options.title))

            $tab.appendTo($tabs)
            $panel.appendTo($panels)
            $more.appendTo($moreBox)

            $tab.data('options', $.extend({}, options))

            if (options.external || (options.url && options.url.isExternalUrl())) {
                $tab.addClass('external')
                this.openExternal(options.url, $panel, options.data)
            } else {
                $tab.removeClass('external')
                tools.reloadTab($panel, options)
            }

            currentIndex = tools.getTabs().length - 1
            this.contextmenu($tab)

            //events
            $tab.on('click', function (e) {
                if (!$(this).hasClass('active'))
                    that.switchTab(options.id)
            }).on('click.zui.navtab.close', '.close', function (e) {
                that.closeTab(options.id)
            }).on('mousedown.zui.navtab.drag', 'a', function (e) {
                $tab.data('zui.navtab.drag', true)

                setTimeout($.proxy(function () {
                    if ($tab.data('zui.navtab.drag'))
                        that.drag(e, $tab, $panel, $more)
                }, that), 150)

                e.preventDefault()
            }).on('mouseup.zui.navtab.drag', 'a', function (e) {
                $tab.data('zui.navtab.drag', false)
            })

            $more.on('click', function () {
                that.switchTab(options.id)
            })
        }

        tools.switchTab(currentIndex)
        tools.scrollCurrent()
    }

    Navtab.prototype.closeTab = function (tabid) {
        var index = this.tools.indexTabId(tabid)

        if (index > 0)
            this.tools.closeTab(index)
    }

    Navtab.prototype.closeCurrentTab = function (openTabid) { //openTabid can be empty. close current tab by default, and open the last tab
        if (currentIndex > 0)
            this.tools.closeTab(currentIndex, openTabid)
    }

    Navtab.prototype.closeAllTab = function () {
        this.tools.getTabs().find('> .close').trigger('click')
    }

    Navtab.prototype.reloadFlag = function (tabids) {
        var arr = tabids.split(',')

        for (var i = 0; i < arr.length; i++) {
            var $tab = this.tools.getTab(arr[i].trim())

            if ($tab) {
                if (this.tools.indexTabId(arr[i]) == currentIndex)
                    this.tools.reload($tab, true)
                else
                    $tab.data('reloadFlag', true)
            }
        }
    }

    Navtab.prototype.switchTab = function (tabid) {
        var index = this.tools.indexTabId(tabid)

        this.tools.switchTab(index)
    }

    Navtab.prototype.scrollPrev = function () {
        this.tools.scrollPrev()
    }

    Navtab.prototype.scrollNext = function () {
        this.tools.scrollNext()
    }

    Navtab.prototype.refresh = function (tabid) {
        var $tab, $panel

        if (!tabid) {
            $tab = $currentTab
        } else if (typeof tabid === 'string') {
            $tab = this.tools.getTab(tabid)
        } else {
            $tab = tabid
        }

        if ($tab && $tab.length) {
            $panel = this.tools.getPanel($tab.data('options').id)
            $panel.removeData('zui.clientPaging')

            this.reload($tab.data('options'))
        }
    }

    Navtab.prototype.reload = function (option) {
        var that = this,
                options = $.extend({}, typeof option === 'object' && option),
                $tab = options.id ? this.tools.getTab(options.id) : this.tools.getTabs().eq(currentIndex)

        if ($tab) {
            var op = $tab.data('options')
            var _reload = function () {
                if (options.title && options.title != op.title) {
                    that.tools.updateTit($tab.index(), options.title)
                }
                $tab.data('options', $.extend({}, op, options))
                that.tools.reload($tab, true)
            }

            if (op.reloadWarn) {
                $.zui.alertmsg('confirm', op.reloadWarn, {
                    okCall: function () {
                        _reload()
                    }
                })
            } else {
                _reload()
            }
        }
    }

    Navtab.prototype.reloadForm = function (clearQuery, option) {
        var options = $.extend({}, typeof option === 'object' && option),
                $tab = options.id ? this.tools.getTab(options.id) : $currentTab,
                $panel = options.id ? this.tools.getPanel(options.id) : $currentPanel

        if ($tab && $panel) {
            var op = $tab.data('options'),
                    data = {},
                    pageData = {},
                    $pagerForm = options.form || $panel.find('#pagerForm')

            if ($pagerForm && $pagerForm.length) {
                options.type = options.type || $pagerForm.attr('method') || 'POST'
                options.url = options.url || $pagerForm.attr('action')

                pageData = $pagerForm.serializeJson()

                if (clearQuery) {
                    var pageInfo = $.zui.pageInfo

                    for (var key in pageInfo) {
                        data[pageInfo[key]] = pageData[pageInfo[key]]
                    }
                } else {
                    data = pageData
                }
            }

            options.data = $.extend({}, options.data || {}, data)

            if (!$tab.hasClass('external')) {
                this.tools.reloadTab($panel, options)
            } else {
                this.openExternal(options.url, $panel, options.data)
            }
        }
    }

    Navtab.prototype.getCurrentPanel = function () {
        return this.tools.getPanels().eq(currentIndex)
    }

    Navtab.prototype.openExternal = function (url, $panel, data) {
        var ih = $panel.closest('.navtab-panel').height()
        var that = this;
        if (data && !$.isEmptyObject(data)) {
            url.indexOf('?') ? url += '&' : '?'
            url += $.param(data)
        }
        if ($panel.find('iframe').first().attr('src')) {
            $panel.find('iframe').first().attr('src', url);
        } else {
            //$panel.html(FRAG.externalFrag.replaceAll('{url}', url).replaceAll('{height}', ih +'px'));
            var $frame = $('<iframe>').attr('frameborder', 'no').attr('border', '0').attr('marginwidth', '0').attr('marginheight', '0')
                    .bind('load', function (status) {
                        if (typeof (toastr) == 'object')
                            toastr.clear();
                    })
                    .attr('src', url).height(ih).width('100%').attr('id', $.zui.uuid());
            $panel.append($frame);
        }
    }

    Navtab.prototype.drag = function (e, $tab, $panel, $more) {
        var that = this,
                $lis = that.tools.getTabs(), $panels = that.tools.getPanels(), $mores = that.tools.getMoreLi(),
                $drag = $tabs.next('.zui-navtab-drag'),
                $prev = $tab.prev(), $next = $tab.next(),
                index = $tab.index(), width = $tab.width(),
                oleft = $tab.position().left,
                leftarr = [], newArr = [], newIndex

        if ($lis.length <= 2)
            return

        if (!$drag.length) {
            $drag = $('<div class="zui-navtab-drag" style="position:absolute; top:0; left:1px; width:2px; height:25px; background:#ff6600; display:none;"></div>')
            $drag.insertAfter($tabs)
        }

        $drag.css('left', oleft - 2)

        $tabs.find('> li').each(function () {
            leftarr.push($(this).position().left)
        })

        $tab.find('> a').basedrag({
            move: 'horizontal',
            oleft: oleft,
            drag: function ($target, e, left, top) {
                $tab.addClass('navtab-drag')

                newArr = [left]
                $.merge(newArr, leftarr)
                newArr.sort(function (a, b) {
                    return a - b
                })

                newIndex = $.inArray(left, newArr)
                if (!newIndex)
                    newIndex = 1
                if (newIndex == $lis.length)
                    $drag.css('left', leftarr[newIndex - 1] - 2 + $lis.last().width())
                else
                    $drag.css('left', leftarr[newIndex] - 2)

                $drag.show()
            },
            stop: function () {
                $tab.removeClass('navtab-drag')
                $drag.hide()

                if (index != newIndex) {
                    if (newIndex == $lis.length) {
                        if (index != $lis.length - 1) {
                            $tab.insertAfter($lis.eq(newIndex - 1))
                            $panel.insertAfter($panels.eq(newIndex - 1))
                            $more.insertAfter($mores.eq(newIndex - 1))
                        }
                    } else {
                        $tab.insertBefore($lis.eq(newIndex))
                        $panel.insertBefore($panels.eq(newIndex))
                        $more.insertBefore($mores.eq(newIndex))
                    }
                }
            },
            event: e,
            nounbind: true
        })
    }

    // 获得当前激活的Tab的索引号
    Navtab.prototype.getCurrent = function() {
        return currentIndex;
    }

    // NAVTAB PLUGIN DEFINITION
    // =======================
    function Plugin(option) {
        var args = arguments,
                property = option,
                navtab = 'zui.navtab',
                $body = $('body'),
                datas = $body.data(navtab) || {}

        return this.each(function () {
            var $this = $(this),
                    options = $.extend({}, Navtab.DEFAULTS, typeof option === 'object' && option),
                    id = options && options.id,
                    data

            if (!id) {
                if (datas.current) {
                    id = datas.current.options.id
                } else {
                    id = $.zui.ui.overwriteHomeTab ? 'main' : 'navtab'
                }
            } else {
                if (!id.isNormalID()) {
                    $.zui.debug('Navtab Plugin: ID [' + id + '] ' + $.zui.regional.idChecked)

                    return
                }
            }

            options.id = id
            data = datas && datas[id]

            if (!data) {
                datas[id] = (data = new Navtab(options))
            } else {
                if (typeof option === 'object' && option)
                    $.extend(data.options, option)
            }

            $body.data(navtab, datas)

            if (typeof property === 'string' && $.isFunction(data[property])) {
                [].shift.apply(args)
                if (!args)
                    data[property]()
                else
                    data[property].apply(data, args)
            } else {
                data.openTab()
            }
        })
    }

    var old = $.fn.navtab

    $.fn.navtab = Plugin
    $.fn.navtab.Constructor = Navtab

    // NAVTAB NO CONFLICT
    // =================

    $.fn.navtab.noConflict = function () {
        $.fn.navtab = old
        return this
    }

    // NOT SELECTOR
    // ==============
    $.zui.navtab = function () {
        Plugin.apply($('body'), arguments)
    }

    // NAVTAB DATA-API
    // ==============
    $(document).on('click.zui.navtab.data-api', '[data-toggle="navtab"]', function (e) {
        var $this = $(this), href = $this.attr('href'), data = $this.data(), options = data.options

        if (options) {
            if (typeof options === 'string')
                options = options.toObj()
            if (typeof options === 'object')
                $.extend(data, options)
        }

        if (!data.title)
            data.title = $this.text().trim()
        if (href && !data.url)
            data.url = href

        Plugin.call($this, data)

        e.preventDefault()
    })

}(jQuery);

/* ========================================================================
 * zui-dialog.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    // DIALOG GLOBAL ELEMENTS
    // ======================

    var $resizable
    var $current, shadow, zindex

    $(function () {
        var INIT_DIALOG = function () {
            $resizable = $('#zui-resizable')
            shadow = 'dialogShadow'
            zindex = Dialog.ZINDEX

            $('body').append('<!-- dialog resizable -->').append(FRAG.resizable)
        }

        INIT_DIALOG()
    })

    // DIALOG CLASS DEFINITION
    // ======================
    var Dialog = function (options) {
        this.$element = $('body')
        this.options = options
        this.tools = this.TOOLS()
    }

    Dialog.DEFAULTS = {
        id: null,
        title: 'New Dialog',
        url: null,
        type: 'GET',
        data: {},
        loadingmask: true,
        width: 500,
        height: 300,
        minW: 65,
        minH: 40,
        max: false,
        mask: false,
        resizable: true,
        drawable: true,
        maxable: true,
        minable: true,
        fresh: false,
        onLoad: null,
        beforeClose: null,
        onClose: null
    }

    Dialog.ZINDEX = 10000

    Dialog.prototype.TOOLS = function () {
        var that = this
        var tools = {
            getDefaults: function () {
                return Dialog.DEFAULTS
            },
            init: function ($dialog) {
                var width = that.options.width > that.options.minW ? that.options.width : that.options.minW
                var height = that.options.height > that.options.minH ? that.options.height : that.options.minH
                var wW = $(window).width(),
                        wH = $(window).height(),
                        iTop = that.options.max ? 0 : ((wH - height) / 3)
                //var _Top = $(window).scrollTop();
                //iTop+=_Top;

                if (width > wW)
                    width = wW
                if (height > wH)
                    height = wH

                $dialog
                        .height(height)
                        .width(width)
                        .show()
                        .css({left: (wW - width) / 2, top: 0, opacity: 0.1})
                        .animate({top: iTop > 0 ? iTop : 0, opacity: 1})
                        .addClass(shadow)
                        .find('> .dialogContent').height(height - $('> .dialogHeader', $dialog).outerHeight())
                Do.ready('scrollbar', function () {
                    $('body').css({overflow:'hidden'});
                    $dialog.find('> .dialogContent').perfectScrollbar();
                });

                $('body').find('> .zui-dialog-container').not($dialog).removeClass(shadow)
            },
            reload: function ($dialog, options) {
                var $dialogContent = $dialog.find('> .dialogContent'), onLoad, data = options && options.data, html

                options = options || $dialog.data('options')
                onLoad = options.onLoad ? options.onLoad.toFunc() : null

                $dialog.trigger($.zui.eventType.beforeLoadDialog)

                if (options.url) {
                    if (data) {
                        if (typeof data === 'string') {
                            if (data.trim().startsWith('{')) {
                                data = data.toObj()
                            } else {
                                data = data.toFunc()
                            }
                        }
                        if (typeof data === 'function') {
                            data = data.apply()
                        }
                    }
                    $dialogContent.ajaxUrl({
                        type: options.type || 'GET', url: options.url, data: data || {}, loadingmask: options.loadingmask, callback: function (response) {
                            if (onLoad)
                                onLoad.apply(that, [$dialog])
                            if ($.zui.ui.clientPaging && $dialog.data('zui.clientPaging'))
                                $dialog.pagination('setPagingAndOrderby', $dialog)
                        }
                    })
                } else {
                    if (options.html) {
                        html = options.html
                        if ($.isFunction(html.toFunc()))
                            html = html.toFunc()
                    } else if (options.target) {
                        html = $(options.target).html() || $dialog.data('zui.dialog.target')
                        $(options.target).empty()
                        $dialog.data('zui.dialog.target', html)
                    }

                    $dialogContent.trigger($.zui.eventType.beforeAjaxLoad).html(html).initui()

                    if (onLoad)
                        onLoad.apply(that, [$dialog])
                }
            },
            resizeContent: function ($dialog, width, height) {
                var $dialogContent = $dialog.find('> .dialogContent')

                $dialogContent
                        .css({width: (width - 2), height: (height - $dialog.find('> .dialogHeader').outerHeight())})
                        .resizePageH()

                $(window).trigger($.zui.eventType.resizeGrid)
            }
        }

        return tools
    }

    Dialog.prototype.open = function () {
        var that = this,
                options = that.options,
                $body = $('body'),
                datas = $body.data('zui.dialog'),
                data = datas[options.id],
                $dialog = data && data.dialog
        options.body_overflow = $('body').css('overflow')?$('body').css('overflow'):'auto';
        if (!(options.target || $(options.target).length) && !options.html) {
            if (!options.url && options.href)
                options.url = options.href
            if (!options.url) {
                $.zui.debug('Dialog Plugin: Error trying to open a dialog, url is undefined!')
                return
            } else {
                options.url = decodeURI(options.url).replacePlh()

                if (!options.url.isFinishedTm()) {
                    $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                    $.zui.debug('Dialog Plugin: The new dialog\'s url is incorrect, url: ' + options.url)
                    return
                }

                options.url = encodeURI(options.url)
            }
        } else {
            options.url = undefined
        }
        if ($dialog) { //if the dialog id already exists
            var op = $dialog.data('options')

            this.switchDialog($dialog)

            if ($dialog.is(':hidden'))
                $dialog.show()
            if (options.fresh || options.url != op.url) {
                that.reload(options)
            }
        } else { //open a new dialog
            var dr = $.zui.regional.dialog,
                    dialog = FRAG.dialog
                    .replace('#close#', dr.close)
                    .replace('#maximize#', dr.maximize)
                    .replace('#restore#', dr.restore)
                    .replace('#minimize#', dr.minimize)
                    .replace('#title#', dr.title)

            $dialog = $(dialog)
                    .data('options', $.extend({}, options))
                    .css('z-index', (++zindex))
                    .hide()
                    .appendTo($body)

            $dialog.find('> .dialogHeader > h1 > span.title').html(options.title)

            this.tools.init($dialog)

            if (options.maxable)
                $dialog.find('a.maximize').show()
            else
                $dialog.find('a.maximize').hide()
            if (options.minable)
                $dialog.find('a.minimize').show()
            else
                $dialog.find('a.minimize').hide()
            if (options.max)
                that.maxsize($dialog)
            if (options.mask)
                this.addMask($dialog)

            $dialog.on('click', function (e) {
                if (!$(e.target).data('zui.dialog'))
                    if ($current && $current[0] != $dialog[0])
                        that.switchDialog($dialog)
            }).on('click', '.btn-close', function (e) {
                that.close($dialog)

                e.preventDefault()
            }).on('click', '.dialogHeader > a', function (e) {
                var $a = $(this)

                if ($a.hasClass('close'))
                    that.close($dialog)
                if ($a.hasClass('minimize')) {
                    that.minimize($dialog)
                }
                if ($a.hasClass('maximize')) {
                    that.switchDialog($dialog)
                    that.maxsize($dialog)
                }
                if ($a.hasClass('restore'))
                    that.restore($dialog)

                e.preventDefault()
                e.stopPropagation()
            }).on('dblclick', '.dialogHeader > h1', function (e) {
                if (options.maxable) {
                    if ($dialog.find('> .dialogHeader > a.restore').is(':hidden'))
                        $dialog.find('a.maximize').trigger('click')
                    else
                        $dialog.find('> .dialogHeader > a.restore').trigger('click')
                }
            }).on('mousedown.zui.dialog.drag', '.dialogHeader > h1', function (e) {
                that.switchDialog($dialog)

                if (!options.drawable || $dialog.data('max'))
                    return

                $dialog.data('zui.dialog.task', true)
                setTimeout($.proxy(function () {
                    if ($dialog.data('zui.dialog.task'))
                        that.drag(e, $dialog)
                }, that), 150)

                e.preventDefault()
            }).on('mouseup.zui.dialog.drag', '.dialogHeader > h1', function (e) {
                $dialog.data('zui.dialog.task', false)
            }).on('mousedown.zui.dialog.resize', 'div[class^="resizable"]', function (e) {
                if (!options.drawable || $dialog.data('max'))
                    return false
                if (!options.resizable)
                    return false

                var $bar = $(this)

                that.switchDialog($dialog)
                that.resizeInit(e, $('#zui-resizable'), $dialog, $bar)
                $bar.show()

                e.preventDefault()
            }).on('mouseup.zui.dialog.resize', 'div[class^="resizable"]', function (e) {
                e.preventDefault()
            })

            data.dialog = $dialog
            this.tools.reload($dialog, options)
        }

        $.CurrentDialog = $current = $dialog

        // set current to body data
        datas.current = this
    }

    Dialog.prototype.addMask = function ($dialog) {
        var $mask = $dialog.data('zui.dialog.mask')

        $dialog.wrap('<div style="z-index:' + zindex + '" class="zui-dialog-wrap"></div>')
        $dialog.find('> .dialogHeader > a.minimize').hide()
        if (!$mask || !$mask.length) {
            $mask = $(FRAG.dialogMask)
            $mask.css('z-index', 1).show().insertBefore($dialog)
            $dialog.data('zui.dialog.mask', $mask)
            $('body').css({'overflow': 'hidden'});
        }
    }

    Dialog.prototype.refresh = function (id) {
        if (id && typeof id === 'string') {
            var arr = id.split(','), datas = $('body').data('zui.dialog')

            for (var i = 0; i < arr.length; i++) {
                var $dialog = datas[arr[i].trim()].dialog

                if ($dialog) {
                    $dialog.removeData('zui.clientPaging')
                    this.tools.reload($dialog)
                }
            }
        } else {
            if ($current) {
                $current.removeData('zui.clientPaging')
                this.tools.reload($current)
            }
        }
    }

    Dialog.prototype.reload = function (option) {
        var that = this,
                options = $.extend({}, typeof option === 'object' && option),
                datas = $('body').data('zui.dialog'),
                $dialog = (options.id && datas[options.id] && datas[options.id].dialog) || that.getCurrent()

        if ($dialog && $dialog.length) {
            var op = $dialog.data('options')

            options = $.extend({}, op, options)

            var _reload = function () {
                var $dialogContent = $dialog.find('> .dialogContent')

                if (options.width != op.width) {
                    if (options.max) {
                        $dialog.animate({width: options.width}, 'normal', function () {
                            $dialogContent.width(options.width)
                        })
                    } else {
                        $dialog.width(options.width)
                        $dialogContent.width(options.width)
                    }
                }
                if (options.height != op.height) {
                    if (options.max) {
                        $dialog.animate({height: options.height}, 'normal', function () {
                            $dialogContent.height(options.height - $dialog.find('> .dialogHeader').outerHeight() - 6).resizePageH()
                        })
                    } else {
                        $dialog.height(options.height)
                        $dialogContent.height(options.height - $dialog.find('> .dialogHeader').outerHeight() - 6)
                    }
                }
                if (options.maxable != op.maxable) {
                    if (options.maxable)
                        $dialog.find('a.maximize').show()
                    else
                        $dialog.find('a.maximize').hide()
                }
                if (options.minable != op.minable) {
                    if (options.minable)
                        $dialog.find('a.minimize').show()
                    else
                        $dialog.find('a.minimize').hide()
                }
                if (options.max != op.max)
                    if (options.max)
                        setTimeout(that.maxsize($dialog), 10)
                if (options.mask != op.mask) {
                    if (options.mask) {
                        that.addMask($dialog)
                    }
                }
                if (options.title != op.title) {
                    $dialog.find('> .dialogHeader > h1 > span.title').html(options.title)
                }

                $dialog.data('options', $.extend({}, options))

                that.tools.reload($dialog, op)
            }

            if (op.reloadWarn) {
                $dialog.alertmsg('confirm', op.reloadWarn, {
                    okCall: function () {
                        _reload()
                    }
                })
            } else {
                _reload()
            }
        }
    }

    Dialog.prototype.reloadForm = function (clearQuery, option) {
        var options = $.extend({}, typeof option === 'object' && option),
                datas = $('body').data('zui.dialog'),
                $dialog

        if (options.id) {
            if (datas && datas[options.id])
                $dialog = datas[options.id].dialog
        } else {
            $dialog = $current
        }

        if ($dialog) {
            var op = $dialog.data('options'),
                    data = {},
                    pageData = {},
                    $pagerForm = options.form || $dialog.find('#pagerForm')

            if ($pagerForm && $pagerForm.length) {
                options.type = options.type || $pagerForm.attr('method') || 'POST'
                options.url = options.url || $pagerForm.attr('action')

                pageData = $pagerForm.serializeJson()

                if (clearQuery) {
                    var pageInfo = $.zui.pageInfo

                    for (var key in pageInfo) {
                        data[pageInfo[key]] = pageData[pageInfo[key]]
                    }
                } else {
                    data = pageData
                }
            }

            options.data = $.extend({}, options.data || {}, data)

            this.tools.reload($dialog, options)
        }
    }

    Dialog.prototype.getCurrent = function () {
        return $current
    }

    Dialog.prototype.switchDialog = function ($dialog) {
        var index = $dialog.css('z-index')

        if ($current && $current != $dialog) {
            if ($current.data('options').mask)
                return

            var cindex = $current.css('z-index'),
                    datas = $('body').data('zui.dialog')

            $current.css('z-index', index)
            $dialog.css('z-index', cindex)
            $.CurrentDialog = $current = $dialog

            // set current to body data
            datas.current = this
        }

        $dialog.addClass(shadow)
        $('body').find('> .zui-dialog-container').not($dialog).removeClass(shadow)
    }

    Dialog.prototype.close = function (dialog) {
        var that = this,
                datas = $('body').data('zui.dialog'),
                $dialog = (typeof dialog === 'string') ? datas[dialog].dialog : dialog,
                $mask = $dialog.data('zui.dialog.mask'),
                options = $dialog.data('options'),
                target = $dialog.data('zui.dialog.target'),
                beforeClose = options.beforeClose ? options.beforeClose.toFunc() : null,
                onClose = options.onClose ? options.onClose.toFunc() : null,
                canClose = true

        if (!$dialog || !options)
            return
        if (beforeClose)
            canClose = beforeClose.apply(that, [$dialog])
        if (!canClose) {
            that.switchDialog($dialog)
            return
        }
        if (options.target && target)
            $(options.target).html(target)
        if ($mask && $mask.length) {
            $('body').css({'overflow': options.body_overflow});
            $mask.remove()
            $dialog.unwrap()
        }

        $dialog.animate({top: -$dialog.outerHeight(), opacity: 0.1}, 'normal', function () {
            delete datas[options.id]

            $dialog.trigger($.zui.eventType.beforeCloseDialog).remove()
            if (onClose)
                onClose.apply(that)

            $.CurrentDialog = $current = null

            var $dialogs = $('body').find('.zui-dialog-container'),
                    $_current = null

            if ($dialogs.length) {
                $_current = that.$element.getMaxIndexObj($dialogs)
            } else {
                zindex = Dialog.ZINDEX
            }
            if ($_current && $_current.is(':visible')) {
                $.CurrentDialog = $current = $_current
                that.switchDialog($_current)
            }
        })
    }

    Dialog.prototype.closeCurrent = function () {
        this.close($current)
    }

    Dialog.prototype.maxsize = function ($dialog) {
        $dialog.data('original', {
            top: $dialog.css('top'),
            left: $dialog.css('left'),
            width: $dialog.css('width'),
            height: $dialog.css('height')
        }).data('max', true)

        $dialog.find('> .dialogHeader > a.maximize').hide()
        $dialog.find('> .dialogHeader > a.restore').show()

        var iContentW = $(window).width()- 10,
                iContentH = $(window).height() - 10

        $dialog.css({top: '5px', left: '5px', width: iContentW, height: iContentH})

        this.tools.resizeContent($dialog, iContentW, iContentH)
    }

    Dialog.prototype.restore = function ($dialog) {
        var original = $dialog.data('original'),
                dwidth = parseInt(original.width),
                dheight = parseInt(original.height)

        $dialog.css({
            top: original.top,
            left: original.left,
            width: dwidth,
            height: dheight
        })

        this.tools.resizeContent($dialog, dwidth, dheight)

        $dialog.find('> .dialogHeader > a.maximize').show()
        $dialog.find('> .dialogHeader > a.restore').hide()
        $dialog.data('max', false)
    }

    Dialog.prototype.minimize = function ($dialog) {
        $dialog.hide()
        var $dialogs = $('body').find('.zui-dialog-container:visible'),
                $_current = null

        if ($dialogs.length) {
            $_current = this.$element.getMaxIndexObj($dialogs)
        }
        if ($_current)
            this.switchDialog($_current)
    }

    Dialog.prototype.drag = function (e, $dialog) {
        var $shadow = $('#zui-dialogProxy')

        $dialog.find('> .dialogContent').css('opacity', '.3')
        $dialog.basedrag({
            selector: '> .dialogHeader',
            stop: function () {
                $dialog
                        .css({left: $dialog.css('left'), top: $dialog.css('top')})
                        .find('> .dialogContent').css('opacity', 1)
            },
            event: e,
            nounbind: true
        })
    }

    Dialog.prototype.resizeDialog = function ($resizable, $dialog, target) {
        var tmove,
                oleft = parseInt($resizable.css('left')),
                otop = parseInt($resizable.css('top')),
                height = parseInt($resizable.css('height')),
                width = parseInt($resizable.css('width'))

        if (target == 'n' || target == 'nw')
            tmove = parseInt($dialog.css('top')) - otop
        else
            tmove = height - parseInt($dialog.css('height'))

        if (otop < 0)
            otop = 0

        $dialog
                .css({top: otop, left: oleft, width: width + 2, height: height + 1})
                .find('> .dialogContent').css('width', width)

        if (target != 'w' && target != 'e') {
            var $dialogContent = $dialog.find('> .dialogContent')

            $dialogContent
                    .css({height: height - $dialog.find('> .dialogHeader').outerHeight()})
                    .resizePageH()
            Do.ready('scrollbar', function () {
                $('body').css({overflow:'hidden'});
                $dialogContent.perfectScrollbar();
            });
        }
        $(window).trigger($.zui.eventType.resizeGrid)
    }

    Dialog.prototype.resizeInit = function (e, $resizable, $dialog, $bar) {
        var that = this, target = $bar.attr('tar')

        $('body').css('cursor', target + '-resize')
        $resizable
                .css({
                    top: $dialog.css('top'),
                    left: $dialog.css('left'),
                    height: $dialog.outerHeight(),
                    width: $dialog.css('width')
                })
                .show()

        if (!this.options.dragCurrent) {
            this.options.dragCurrent = {
                $resizable: $resizable,
                $dialog: $dialog,
                target: target,
                oleft: parseInt($resizable.css('left')) || 0,
                owidth: parseInt($resizable.css('width')) || 0,
                otop: parseInt($resizable.css('top')) || 0,
                oheight: parseInt($resizable.css('height')) || 0,
                ox: e.pageX || e.screenX,
                oy: e.pageY || e.clientY
            }
            $(document).on('mouseup.zui.dialog.resize', $.proxy(that.resizeStop, that))
            $(document).on('mousemove.zui.dialog.resize', $.proxy(that.resizeStart, that))
        }
    }

    Dialog.prototype.resizeStart = function (e) {
        var current = this.options.dragCurrent

        if (!current)
            return
        if (!e)
            var e = window.event

        var lmove = (e.pageX || e.screenX) - current.ox,
                tmove = (e.pageY || e.clientY) - current.oy,
                $mask = current.$dialog.data('zui.dialog.mask')

        if (!$mask || !$mask.length)
            if ((e.pageY || e.clientY) <= 0 || (e.pageY || e.clientY) >= ($(window).height() - current.$dialog.find('> .dialogHeader').outerHeight()))
                return

        var target = current.target,
                width = current.owidth,
                height = current.oheight

        if (target != 'n' && target != 's')
            width += (target.indexOf('w') >= 0) ? -lmove : lmove
        if (width >= this.options.minW) {
            if (target.indexOf('w') >= 0)
                current.$resizable.css('left', (current.oleft + lmove))
            if (target != 'n' && target != 's')
                current.$resizable.css('width', width)
        }
        if (target != 'w' && target != 'e')
            height += (target.indexOf('n') >= 0) ? -tmove : tmove
        if (height >= this.options.minH) {
            if (target.indexOf('n') >= 0)
                current.$resizable.css('top', (current.otop + tmove))
            if (target != 'w' && target != 'e')
                current.$resizable.css('height', height)
        }
    }

    Dialog.prototype.resizeStop = function (e) {
        var current = this.options.dragCurrent

        if (!current)
            return false

        $(document).off('mouseup.zui.dialog.resize').off('mousemove.zui.dialog.resize')

        this.options.dragCurrent = null
        this.resizeDialog(current.$resizable, current.$dialog, current.target)

        $('body').css('cursor', '')
        current.$resizable.hide()
    }

    // DIALOG PLUGIN DEFINITION
    // =======================

    function Plugin(option) {
        var args = arguments,
                property = option,
                dialog = 'zui.dialog',
                $body = $('body'),
                datas = $body.data(dialog) || {}

        return this.each(function () {
            var $this = $(this),
                    options = $.extend({}, Dialog.DEFAULTS, typeof option === 'object' && option),
                    id = options && options.id,
                    data

            if (!id) {
                if (datas.current)
                    id = datas.current.options.id
                else
                    id = 'dialog'
            } else {
                if (!id.isNormalID()) {
                    $.zui.debug('Dialog Plugin: ID [' + id + '] ' + $.zui.regional.idChecked)

                    return
                }
            }

            options.id = id
            data = datas && datas[id]

            if (!data) {
                datas[id] = (data = new Dialog(options))
            } else {
                if (typeof option === 'object' && option)
                    $.extend(data.options, option)
            }

            $body.data(dialog, datas)

            if (typeof property === 'string' && $.isFunction(data[property])) {
                [].shift.apply(args)
                if (!args)
                    data[property]()
                else
                    data[property].apply(data, args)
            } else {
                //data = new Dialog(this, options)
                data.open()
            }
        })
    }

    var old = $.fn.dialog

    $.fn.dialog = Plugin
    $.fn.dialog.Constructor = Dialog

    // DIALOG NO CONFLICT
    // =================

    $.fn.dialog.noConflict = function () {
        $.fn.dialog = old
        return this
    }

    // NOT SELECTOR
    // ==============

    $.zui.dialog = function () {
        Plugin.apply($('body'), arguments)
    }

    // DIALOG DATA-API
    // ==============

    $(document).on('click.zui.dialog.data-api', '[data-toggle="dialog"]', function (e) {
        var $this = $(this), href = $this.attr('href'), data = $this.data(), options = data.options

        if (options) {
            if (typeof options === 'string')
                options = options.toObj()
            if (typeof options === 'object')
                $.extend(data, options)
        }

        if (!data.title)
            data.title = $this.text().trim()
        if (href && !data.url)
            data.url = href

        Plugin.call($this, data)

        e.preventDefault()
    })

}(jQuery);
/* ========================================================================
 * ajaxtab.js  v1.3 beta2
 * ======================================================================== */
+function ($) {
    'use strict';

    // AJAXTAB CLASS DEFINITION
    // ======================

    var Ajaxtab = function(element, options) {
        this.$element = $(element)
        this.options  = options
    }

    Ajaxtab.DEFAULTS = {
        url    : undefined,
        target : undefined,
        reload : false
    }

    Ajaxtab.prototype.init = function() {
        var options = this.options

        if (!(options.url)) {
            $.zui.debug('Ajaxtab Plugin: Error trying to open a tab, url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh(this.$element.closest('.unitBox'))

            if (!options.url.isFinishedTm()) {
                this.$element.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('Ajaxtab Plugin: The new ajaxtab\'s url is incorrect, url: '+ options.url)
                return
            }

            options.url = encodeURI(options.url)
        }
        if (!options.target) {
            $.zui.debug('Ajaxtab Plugin: Attribute \'target\' is not defined!')
            return
        }
        if (options.reload) {
            this.load()
        } else {
            var reload = this.$element.data('zui.ajaxtab.reload')

            if (!reload) this.load()
            else this.$element.tab('show')
        }
    }

    Ajaxtab.prototype.load = function() {
        var $element = this.$element
        var options  = this.options

        $(options.target).ajaxUrl({
            url      : options.url,
            data     : {},
            callback : function() {
                $element.data('zui.ajaxtab.reload', true).tab('show')
            }
        })
    }

    // AJAXTAB PLUGIN DEFINITION
    // =======================

    function Plugin(option) {
        var args     = arguments
        var property = option

        return this.each(function () {
            var $this   = $(this)
            var options = $.extend({}, Ajaxtab.DEFAULTS, $this.data(), typeof option === 'object' && option)
            var data    = $this.data('zui.ajaxtab')

            if (!data) $this.data('zui.ajaxtab', (data = new Ajaxtab(this, options)))
            if (typeof property === 'string' && $.isFunction(data[property])) {
                [].shift.apply(args)
                if (!args) data[property]()
                else data[property].apply(data, args)
            } else {
                data.init()
            }
        })
    }

    var old = $.fn.ajaxtab

    $.fn.ajaxtab             = Plugin
    $.fn.ajaxtab.Constructor = Ajaxtab

    // AJAXTAB NO CONFLICT
    // =================

    $.fn.ajaxtab.noConflict = function () {
        $.fn.ajaxtab = old
        return this
    }

    // AJAXTAB DATA-API
    // ==============

    $(document).on('click.zui.ajaxtab.data-api', '[data-toggle="ajaxtab"]', function(e) {
        var $this   = $(this)
        var options = $this.data()

        if (!options.url) options.url = $this.attr('href')
        Plugin.call($this, options)

        e.preventDefault()
    })

}(jQuery);
var _log = console.log;
console.alert = function(){
    /msie|edge/gi.test(navigator.userAgent)?
    _log.call(console, [].slice.call(arguments).join(' ')):
    _log.call(console, '%c' + [].slice.call(arguments).join(' '), 'color:#ff0000;font-size:24px;');
}
var __homepage__ = 'http://www.haolie.net';
var __email__ = 'htmambo#gmail.com';
var __qq__ = '315821652';
var __name__ = 'JYCMS';
/msie|edge/gi.test(navigator.userAgent)?(console.log(__name__)):(console.log(
    "%c%s\x0d\x0a%c作者：IT果农 email:%s QQ:%s",
    'font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;font-size:64px;color:#00bbee;-webkit-text-fill-color:#00bbee;-webkit-text-stroke: 1px #00bbee;',
    __name__,
    "font-size:12px;color:#999999;",
    __email__,
    __qq__
));
var BROWSER = {};
var USERAGENT = navigator.userAgent.toLowerCase();
//browserVersion({'ie':'msie','firefox':'','chrome':'','opera':'','safari':'','mozilla':'','webkit':'','maxthon':'','qq':'qqbrowser'});
if(BROWSER.safari) {
    BROWSER.firefox = true;
}
BROWSER.opera = BROWSER.opera ? opera.version() : 0;

HTMLNODE = document.getElementsByTagName('head')[0].parentNode;
if(BROWSER.ie) {
    HTMLNODE.className = 'ie_all ie' + parseInt(BROWSER.ie);
}
$.browser = {};
$.browser.mozilla = /firefox/.test(navigator.userAgent.toLowerCase());
$.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
$.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
$.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());

window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) {
    console.alert('JS出错信息');
    console.error("错误信息：" , errorMessage);
    console.log("出错文件：" , scriptURI);
    console.log("出错行号：" , lineNumber);
    console.log("出错列号：" , columnNumber);
    console.log("错误详情：" , errorObj);
    $('.zui-ajax-mask').parent().trigger('zui.ajaxError');
    //$.zui.alertmsg('error', 'JS代码出错，详细信息请查看CONSOLE!')
    return true;
}
